Skip to content

Commit b566598

Browse files
Morten Johan SørvigTarja Sundqvist
Morten Johan Sørvig
authored and
Tarja Sundqvist
committed
wasm: don’t deadlock on event processing
emscripten_async_run_in_main_runtime_thread_ schedules an async call on the on the main thread. However, the calls are ordered, also in respect to _synchronous_ calls to the main thread (for example those made during file write/flush). Making a synchronous call from a secondary thread may then cause Emscripten to service previously scheduled async calls during the synchronous call. This can cause a deadlock if: - a secondary thread makes a sync call while holding a lock, and - a previously scheduled async call attempt to acquire the same lock on the main thread. (See emscripten-core/emscripten#10155 for sample code) Avoid this case by adding a second zero-timer async call; this way Qt should process events when the main thread becomes idle. Change-Id: I221fe4e25bbb1a56627e63c3d1809e40ccefb030 Reviewed-by: Lorn Potter <[email protected]> (cherry picked from commit 4035fdd)
1 parent d6e0964 commit b566598

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

src/plugins/platforms/wasm/qwasmeventdispatcher.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,15 @@ void QWasmEventDispatcher::doMaintainTimers()
193193
void QWasmEventDispatcher::wakeUp()
194194
{
195195
#ifdef EMSCRIPTEN_HAS_ASYNC_RUN_IN_MAIN_RUNTIME_THREAD
196-
if (!emscripten_is_main_runtime_thread())
197-
if (m_hasMainLoop)
198-
emscripten_async_run_in_main_runtime_thread_(EM_FUNC_SIG_VI, (void*)(&QWasmEventDispatcher::mainThreadWakeUp), this);
196+
if (!emscripten_is_main_runtime_thread() && m_hasMainLoop) {
197+
198+
// Make two-step async call to mainThreadWakeUp in order to make sure the
199+
// call is made at a point where the main thread is idle.
200+
void (*intermediate)(void *) = [](void *eventdispatcher){
201+
emscripten_async_call(QWasmEventDispatcher::mainThreadWakeUp, eventdispatcher, 0);
202+
};
203+
emscripten_async_run_in_main_runtime_thread_(EM_FUNC_SIG_VI, (void *)intermediate, this);
204+
}
199205
#endif
200206
QEventDispatcherUNIX::wakeUp();
201207
}

0 commit comments

Comments
 (0)