From ce7217797305a0bf1feb7f114ac1a16b3943226f Mon Sep 17 00:00:00 2001 From: Hans Dijkema Date: Sat, 18 Apr 2026 16:31:12 +0200 Subject: [PATCH] events on quit --- rktwebview.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/rktwebview.cpp b/rktwebview.cpp index 1da049e..cf27219 100644 --- a/rktwebview.cpp +++ b/rktwebview.cpp @@ -37,6 +37,27 @@ //#define DEBUG +#ifdef __linux +static int sleep_ms(long msec) +{ + struct timespec ts; + int res; + + if (msec < 0) { + return -1; + } + + ts.tv_sec = msec / 1000; + ts.tv_nsec = (msec % 1000) * 1000000; + + res = nanosleep(&ts, &ts); + return res; +} +#endif + +#define YIELD() sleep_ms(5) + + ///////////////////////////////////////////////////////////////////// // Utility functions ///////////////////////////////////////////////////////////////////// @@ -70,6 +91,8 @@ typedef struct { bool alive_go_on; std::thread *alive_thread; bool alive_error; + + bool verbose; } Handle_t; Handle_t *handler = nullptr; @@ -200,22 +223,35 @@ bool runRktWebview(Handle_t *handler) #define EVT_GUARD_STOP -93273 #define EVT_ALIVE_ERROR -94328 -#define WAIT_ON_EVENT_MS (10 * 1000) +#define WAIT_ON_EVENT_MS (2 * 1000) #define ALIVE_MESSAGE_INTERVAL_S 5 // Should be smaller than 10 seconds #define MAX_WAIT_RESULT (2 * 1000) // Maximum wait in milliseconds for a result per time #define MAX_ALIVE_ACK_TIME (10 * 1000) void rkt_evt_guard(void) { + INFO0("Starting rkt_evt_guard\n"); while(handler->guard_go_on) { int wv; std::string data; if (handler->event_queue->dequeue(wv, data, WAIT_ON_EVENT_MS)) { + if (handler->verbose) { + INFO2("Got event wv = %d, %s\n", wv, data.c_str()); + } if (wv != EVT_GUARD_STOP) { - handler->evt_queue->enqueue(wv, data); - handler->evt_cb(1); + if (handler->evt_cb != nullptr) { // evt_cb could be cleared to null + handler->evt_queue->enqueue(wv, data); + handler->evt_cb(1); + } else { + INFO0("evt_cb = null\n"); + } } else { INFO0("Got stop message (evt_guard)\n"); + handler->guard_go_on = false; + } + } else { + if (handler->verbose) { + INFO0("Got nothing, verbose = true\n"); } } } @@ -260,13 +296,19 @@ void rkt_webview_cleanup() // So we would need to cleanup at exit of racket/drracket. // Cleaning up when exiting the current custodian is not enough. + handler->verbose = true; + sleep_ms(3000); + if (handler->valid) { if (handler->evt_cb != nullptr) { - INFO0("Stopping evt_guard\n"); - handler->guard_go_on = false; - handler->event_queue->enqueue(EVT_GUARD_STOP); + INFO0("Stopping evt_guard (enqueuing evt_guard_stop)\n"); handler->event_queue->enqueue(EVT_GUARD_STOP); + INFO0("yielding current thread and hopefully activating evt_guard thread\n"); + YIELD(); + sleep_ms(1000); + INFO0("joining guard thread\n"); handler->guard_thread->join(); + INFO0("Deleting guard thread\n"); delete handler->guard_thread; handler->guard_thread = nullptr; } @@ -336,6 +378,7 @@ void rkt_webview_init() handler->name = buf; handler->function_calls = 0; handler->events = 0; + handler->verbose = true; handler->shm_size = SHM_SIZE; handler->shm = new Shm(handler->name.data(), handler->shm_size, true);