Finalization & synchronization. Making sure racket does not get stuck on a mutex.

This commit is contained in:
2026-04-20 18:19:58 +02:00
parent 490b89be38
commit 2b107f8f73
2 changed files with 34 additions and 7 deletions

View File

@@ -87,6 +87,7 @@ typedef struct {
std::string log_file;
void (*evt_cb)(int entries);
std::mutex evt_cb_mutex;
MemQueue *evt_queue;
std::thread *guard_thread;
bool guard_go_on;
@@ -226,6 +227,8 @@ bool runRktWebview(Handle_t *handler)
#define EVT_GUARD_STOP -93273
#define EVT_ALIVE_ERROR -94328
#define EVT_NULL -95372
#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
@@ -241,15 +244,20 @@ void rkt_evt_guard(void)
if (handler->verbose) {
INFO2("Got event wv = %d, %s\n", wv, data.c_str());
}
if (wv != EVT_GUARD_STOP) {
if (wv != EVT_GUARD_STOP && wv != EVT_NULL) {
handler->evt_queue->enqueue(wv, data);
handler->evt_cb_mutex.lock();
if (handler->evt_cb != nullptr) { // evt_cb could be cleared to null
INFO2("Calling evt_cb with %d, %s\n", wv, data.c_str());
handler->evt_cb(1);
INFO0("done\n");
} else {
INFO0("evt_cb = null\n");
}
handler->evt_cb_mutex.unlock();
} else if (wv == EVT_NULL) {
INFO0("Got NULL message (evt_guard)\n");
} else {
INFO0("Got stop message (evt_guard)\n");
handler->guard_go_on = false;
@@ -261,6 +269,7 @@ void rkt_evt_guard(void)
}
}
INFO0("Leaving rkt_evt_guard\n");
}
@@ -303,9 +312,15 @@ void rkt_webview_cleanup()
INFO0("rkt_webview_cleanup - cleaning up\n");
handler->verbose = true;
handler->event_queue->enqueue(EVT_NULL);
//sleep_ms(1000); // Why is this second so important?
// I just don't get why the evt_guard thread is blocking and getting core dumped
// on the thread join, if this second is not given
// (to racket?).
if (handler->valid) {
if (handler->guard_thread != nullptr) {
handler->evt_cb_mutex.lock();
if (handler->evt_cb != nullptr) {
INFO0("Clearing evt_guard callback to null\n");
handler->evt_cb = nullptr;
@@ -314,6 +329,7 @@ void rkt_webview_cleanup()
}
INFO0("Stopping evt_guard (enqueuing evt_guard_stop)\n");
handler->event_queue->enqueue(EVT_GUARD_STOP);
handler->evt_cb_mutex.unlock();
INFO0("yielding current thread and hopefully activating evt_guard thread\n");
YIELD();
INFO0("joining guard thread\n");
@@ -449,14 +465,25 @@ static inline bool validHandle()
#define FAIL_CALL_JS if (!validHandle()) { return nullptr; }
#define FAIL_INFO FAIL_CALL_JS
void rkt_webview_register_evt_callback(void (*f)(int))
int rkt_webview_register_evt_callback(void (*f)(int))
{
RKT_WEBVIEW_INIT;
handler->evt_cb = f;
if (handler->guard_thread == nullptr) {
handler->guard_go_on = true;
handler->guard_thread = new std::thread(rkt_evt_guard);
if (handler->evt_cb_mutex.try_lock()) {
INFO1("registering callback %p\n", f);
handler->evt_cb = f;
if (handler->guard_thread == nullptr) {
handler->guard_go_on = true;
handler->guard_thread = new std::thread(rkt_evt_guard);
INFO0("guard thread started\n");
}
handler->evt_cb_mutex.unlock();
return 1;
} else {
WARN1("Cannot aquire lock for registering callback %p\n", f);
return 0;
}
}