VM: attempt to cancel blocking system calls when ctrl-c is pressed
Windows runs ctrl-c in its own thread and doesn't by itself interrupt blocking system calls when it is pressed. Therefore you have to manually send an interrupt signal to the stuck thread.db4
parent
e2eebdec4d
commit
0226718a82
|
@ -1,6 +1,14 @@
|
|||
#include "master.hpp"
|
||||
|
||||
VM_C_API int wmain(int argc, wchar_t** argv) {
|
||||
HANDLE proc = GetCurrentProcess();
|
||||
HANDLE thread = GetCurrentThread();
|
||||
BOOL res = DuplicateHandle(proc, thread, proc,
|
||||
&factor::boot_thread, GENERIC_ALL, FALSE, 0);
|
||||
if (!res) {
|
||||
factor::fatal_error("DuplicateHandle() failed", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
factor::init_globals();
|
||||
factor::start_standalone_factor(argc, argv);
|
||||
return 0;
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace factor {
|
||||
|
||||
HANDLE boot_thread;
|
||||
|
||||
DWORD current_vm_tls_key;
|
||||
|
||||
void init_mvm() {
|
||||
|
|
|
@ -249,6 +249,26 @@ VM_C_API LONG exception_handler(PEXCEPTION_RECORD e, void* frame, PCONTEXT c,
|
|||
return ExceptionContinueSearch;
|
||||
}
|
||||
|
||||
/* On Unix SIGINT (ctrl-c) automatically interrupts blocking io system
|
||||
calls. It doesn't on Windows, so we need to manually send some
|
||||
cancellation requests to unblock the thread. */
|
||||
VOID CALLBACK dummy_cb (ULONG_PTR dwParam) { }
|
||||
|
||||
static void wake_up_thread(HANDLE thread) {
|
||||
if (!CancelSynchronousIo(thread)) {
|
||||
DWORD err = GetLastError();
|
||||
/* CancelSynchronousIo() didn't find anything to cancel, let's try
|
||||
with QueueUserAPC() instead. */
|
||||
if (err == ERROR_NOT_FOUND) {
|
||||
if (!QueueUserAPC(&dummy_cb, thread, NULL)) {
|
||||
fatal_error("QueueUserAPC() failed", GetLastError());
|
||||
}
|
||||
} else {
|
||||
fatal_error("CancelSynchronousIo() failed", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL WINAPI ctrl_handler(DWORD dwCtrlType) {
|
||||
switch (dwCtrlType) {
|
||||
case CTRL_C_EVENT: {
|
||||
|
@ -259,6 +279,10 @@ static BOOL WINAPI ctrl_handler(DWORD dwCtrlType) {
|
|||
FACTOR_ASSERT(thread_vms.size() == 1);
|
||||
factor_vm* vm = thread_vms.begin()->second;
|
||||
vm->safepoint.enqueue_fep(vm);
|
||||
|
||||
/* Before leaving the ctrl_handler, try and wake up the main
|
||||
thread. */
|
||||
wake_up_thread(factor::boot_thread);
|
||||
return TRUE;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -88,4 +88,6 @@ inline static void breakpoint() { DebugBreak(); }
|
|||
#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void)0
|
||||
#define FUNCTION_CODE_POINTER(ptr) ptr
|
||||
#define FUNCTION_TOC_POINTER(ptr) ptr
|
||||
|
||||
extern HANDLE boot_thread;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue