#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;
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: {
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:
#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;
}