From 0538929847a9c7dd527e41c42ad874e3acf8ab56 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Sat, 18 Sep 2021 12:02:15 +0100 Subject: wpe: context thread dispatch fixes Use dedicated mutex/cond/flag for jobs being dispatched in the context thread. The previous code was signalling the thread startup condition, which is wrong. When WPEContextThread::dispatch() is invoked it means the thread has already correctly been started up. Part-of: --- ext/wpe/WPEThreadedView.cpp | 53 ++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/ext/wpe/WPEThreadedView.cpp b/ext/wpe/WPEThreadedView.cpp index cbc5b9f4b..d3c85b5a6 100644 --- a/ext/wpe/WPEThreadedView.cpp +++ b/ext/wpe/WPEThreadedView.cpp @@ -98,30 +98,49 @@ WPEContextThread::~WPEContextThread() template void WPEContextThread::dispatch(Function func) { - struct Payload { + struct Job { + Job(Function& f) + : func(f) + { + g_mutex_init(&mutex); + g_cond_init(&cond); + dispatched = FALSE; + } + ~Job() { + g_mutex_clear(&mutex); + g_cond_clear(&cond); + } + + void dispatch() { + GMutexHolder lock(mutex); + func(); + dispatched = TRUE; + g_cond_signal(&cond); + } + + void waitCompletion() { + GMutexHolder lock(mutex); + while(!dispatched) { + g_cond_wait(&cond, &mutex); + } + } + Function& func; + GMutex mutex; + GCond cond; + gboolean dispatched; }; - struct Payload payload { func }; + struct Job job(func); GSource* source = g_idle_source_new(); g_source_set_callback(source, [](gpointer data) -> gboolean { - auto& view = WPEContextThread::singleton(); - GMutexHolder lock(view.threading.mutex); - - auto* payload = static_cast(data); - payload->func(); - - g_cond_signal(&view.threading.cond); + auto* job = static_cast(data); + job->dispatch(); return G_SOURCE_REMOVE; - }, &payload, nullptr); + }, &job, nullptr); g_source_set_priority(source, G_PRIORITY_DEFAULT); - - { - GMutexHolder lock(threading.mutex); - g_source_attach(source, glib.context); - g_cond_wait(&threading.cond, &threading.mutex); - } - + g_source_attach(source, glib.context); + job.waitCompletion(); g_source_unref(source); } -- cgit v1.2.1