1
0
mirror of https://github.com/janet-lang/janet synced 2025-10-06 19:42:29 +00:00

Use SetEvent rather than QueueUserAPC on Windows

This commit is contained in:
Michael Camilleri
2025-09-16 10:24:24 +09:00
parent 8e7b1e9ce0
commit aca5428846
2 changed files with 26 additions and 6 deletions

View File

@@ -117,6 +117,9 @@ typedef struct {
double sec;
JanetVM *vm;
JanetFiber *fiber;
#ifdef JANET_WINDOWS
HANDLE cancel_event;
#endif
} JanetThreadedTimeout;
#define JANET_MAX_Q_CAPACITY 0x7FFFFFF
@@ -620,10 +623,14 @@ static void janet_timeout_stop(int sig_num) {
static void handle_timeout_worker(JanetTimeout to, int cancel) {
if (!to.has_worker) return;
#ifdef JANET_WINDOWS
(void) cancel;
QueueUserAPC(janet_timeout_stop, to.worker, 0);
if (cancel && to.worker_event) {
SetEvent(to.worker_event);
}
WaitForSingleObject(to.worker, INFINITE);
CloseHandle(to.worker);
if (to.worker_event) {
CloseHandle(to.worker_event);
}
#else
#ifdef JANET_ANDROID
if (cancel) janet_assert(!pthread_kill(to.worker, SIGUSR1), "pthread_kill");
@@ -693,10 +700,13 @@ static void janet_timeout_cb(JanetEVGenericMessage msg) {
static DWORD WINAPI janet_timeout_body(LPVOID ptr) {
JanetThreadedTimeout tto = *(JanetThreadedTimeout *)ptr;
janet_free(ptr);
SleepEx((DWORD)(tto.sec * 1000), TRUE);
janet_interpreter_interrupt(tto.vm);
JanetEVGenericMessage msg = {0};
janet_ev_post_event(tto.vm, janet_timeout_cb, msg);
DWORD res = WaitForSingleObject(tto.cancel_event, (DWORD)(tto.sec * 1000));
/* only send interrupt message if result is WAIT_TIMEOUT */
if (res == WAIT_TIMEOUT) {
janet_interpreter_interrupt(tto.vm);
JanetEVGenericMessage msg = {0};
janet_ev_post_event(tto.vm, janet_timeout_cb, msg);
}
return 0;
}
#else
@@ -3270,6 +3280,12 @@ JANET_CORE_FN(cfun_ev_deadline,
tto->vm = &janet_vm;
tto->fiber = tocheck;
#ifdef JANET_WINDOWS
HANDLE cancel_event = CreateEvent(NULL, TRUE, FALSE, NULL);
if (NULL == cancel_event) {
janet_free(tto);
janet_panic("failed to create cancel event");
}
tto->cancel_event = cancel_event;
HANDLE worker = CreateThread(NULL, 0, janet_timeout_body, tto, 0, NULL);
if (NULL == worker) {
janet_free(tto);
@@ -3285,6 +3301,9 @@ JANET_CORE_FN(cfun_ev_deadline,
#endif
to.has_worker = 1;
to.worker = worker;
#ifdef JANET_WINDOWS
to.worker_event = cancel_event;
#endif
} else {
to.has_worker = 0;
}

View File

@@ -65,6 +65,7 @@ typedef struct {
int has_worker;
#ifdef JANET_WINDOWS
HANDLE worker;
HANDLE worker_event;
#else
pthread_t worker;
#endif