wasm: unifiy eventdispatcher asyncify code paths
There is no difference between these as far as the suspend/resume functions go; the exiting difference is due to using a more modern API for the jspi implementation. Replace EM_JS() usage with EM_ASYNC_JS(). This allows using await Promise() instead of Asyncify.handleSleep(), and also removes the need for setting ASYNCIFY_IMPORTS. Remove the useJspi() function and the duplicate code paths. Task-number: QTBUG-129746 Change-Id: Id914089868763a1a3d5d575043c29845889f6624 Reviewed-by: Lorn Potter <lorn.potter@qt.io> Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io>
This commit is contained in:
parent
40e364172f
commit
9a2370e434
@ -90,9 +90,6 @@ function (qt_internal_setup_wasm_target_properties wasmTarget)
|
|||||||
target_compile_definitions("${wasmTarget}" INTERFACE QT_HAVE_EMSCRIPTEN_ASYNCIFY)
|
target_compile_definitions("${wasmTarget}" INTERFACE QT_HAVE_EMSCRIPTEN_ASYNCIFY)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Set ASYNCIFY_IMPORTS unconditionally in order to support enabling asyncify at link time.
|
|
||||||
target_link_options("${wasmTarget}" INTERFACE "SHELL:-sASYNCIFY_IMPORTS=qt_asyncify_suspend_js,qt_asyncify_resume_js")
|
|
||||||
|
|
||||||
if(QT_FEATURE_shared)
|
if(QT_FEATURE_shared)
|
||||||
|
|
||||||
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
|
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
|
||||||
|
@ -30,9 +30,6 @@ load(emcc_ver)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Declare async functions
|
|
||||||
QMAKE_LFLAGS += -s ASYNCIFY_IMPORTS=qt_asyncify_suspend_js,qt_asyncify_resume_js
|
|
||||||
|
|
||||||
EMCC_COMMON_LFLAGS += \
|
EMCC_COMMON_LFLAGS += \
|
||||||
-s WASM=1 \
|
-s WASM=1 \
|
||||||
-s MAX_WEBGL_VERSION=2 \
|
-s MAX_WEBGL_VERSION=2 \
|
||||||
|
@ -44,58 +44,14 @@ static bool useAsyncify()
|
|||||||
return qstdweb::haveAsyncify();
|
return qstdweb::haveAsyncify();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool useJspi()
|
|
||||||
{
|
|
||||||
return qstdweb::haveJspi();
|
|
||||||
}
|
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
EM_ASYNC_JS(void, qt_jspi_suspend_js, (), {
|
EM_ASYNC_JS(void, qt_asyncify_suspend_js, (), {
|
||||||
++Module.qtJspiSuspensionCounter;
|
|
||||||
|
|
||||||
await new Promise(resolve => {
|
|
||||||
Module.qtAsyncifyWakeUp.push(resolve);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
EM_JS(bool, qt_jspi_resume_js, (), {
|
|
||||||
if (!Module.qtJspiSuspensionCounter)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
--Module.qtJspiSuspensionCounter;
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
const wakeUp = (Module.qtAsyncifyWakeUp ?? []).pop();
|
|
||||||
if (wakeUp) wakeUp();
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
EM_JS(bool, qt_jspi_can_resume_js, (), {
|
|
||||||
return Module.qtJspiSuspensionCounter > 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
EM_JS(void, init_jspi_support_js, (), {
|
|
||||||
Module.qtAsyncifyWakeUp = [];
|
|
||||||
Module.qtJspiSuspensionCounter = 0;
|
|
||||||
});
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
void initJspiSupport() {
|
|
||||||
init_jspi_support_js();
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_CONSTRUCTOR_FUNCTION(initJspiSupport);
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
EM_JS(void, qt_asyncify_suspend_js, (), {
|
|
||||||
if (Module.qtSuspendId === undefined)
|
if (Module.qtSuspendId === undefined)
|
||||||
Module.qtSuspendId = 0;
|
Module.qtSuspendId = 0;
|
||||||
let sleepFn = (wakeUp) => {
|
|
||||||
Module.qtAsyncifyWakeUp = wakeUp;
|
|
||||||
};
|
|
||||||
++Module.qtSuspendId;
|
++Module.qtSuspendId;
|
||||||
return Asyncify.handleSleep(sleepFn);
|
await new Promise(resolve => {
|
||||||
|
Module.qtAsyncifyWakeUp = resolve;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
EM_JS(void, qt_asyncify_resume_js, (), {
|
EM_JS(void, qt_asyncify_resume_js, (), {
|
||||||
@ -125,28 +81,6 @@ static bool useAsyncify()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool useJspi()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void qt_jspi_suspend_js()
|
|
||||||
{
|
|
||||||
Q_UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool qt_jspi_resume_js()
|
|
||||||
{
|
|
||||||
Q_UNREACHABLE();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool qt_jspi_can_resume_js()
|
|
||||||
{
|
|
||||||
Q_UNREACHABLE();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void qt_asyncify_suspend_js()
|
void qt_asyncify_suspend_js()
|
||||||
{
|
{
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
@ -453,9 +387,8 @@ void QEventDispatcherWasm::wakeUp()
|
|||||||
// event loop. Make sure the thread is unblocked or make it
|
// event loop. Make sure the thread is unblocked or make it
|
||||||
// process events.
|
// process events.
|
||||||
bool wasBlocked = wakeEventDispatcherThread();
|
bool wasBlocked = wakeEventDispatcherThread();
|
||||||
// JSPI does not need a scheduled call to processPostedEvents, as the stack is not unwound
|
|
||||||
// at startup.
|
if (!wasBlocked && isMainThreadEventDispatcher()) {
|
||||||
if (!qstdweb::haveJspi() && !wasBlocked && isMainThreadEventDispatcher()) {
|
|
||||||
{
|
{
|
||||||
LOCK_GUARD(m_mutex);
|
LOCK_GUARD(m_mutex);
|
||||||
if (m_pendingProcessEvents)
|
if (m_pendingProcessEvents)
|
||||||
@ -480,12 +413,10 @@ void QEventDispatcherWasm::handleApplicationExec()
|
|||||||
// using it for the one qApp exec().
|
// using it for the one qApp exec().
|
||||||
// When JSPI is used, awaited async calls are allowed to be nested, so we
|
// When JSPI is used, awaited async calls are allowed to be nested, so we
|
||||||
// proceed normally.
|
// proceed normally.
|
||||||
if (!qstdweb::haveJspi()) {
|
|
||||||
const bool simulateInfiniteLoop = true;
|
const bool simulateInfiniteLoop = true;
|
||||||
emscripten_set_main_loop([](){
|
emscripten_set_main_loop([](){
|
||||||
emscripten_pause_main_loop();
|
emscripten_pause_main_loop();
|
||||||
}, 0, simulateInfiniteLoop);
|
}, 0, simulateInfiniteLoop);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QEventDispatcherWasm::handleDialogExec()
|
void QEventDispatcherWasm::handleDialogExec()
|
||||||
@ -528,15 +459,12 @@ bool QEventDispatcherWasm::wait(int timeout)
|
|||||||
if (timeout > 0)
|
if (timeout > 0)
|
||||||
qWarning() << "QEventDispatcherWasm asyncify wait with timeout is not supported; timeout will be ignored"; // FIXME
|
qWarning() << "QEventDispatcherWasm asyncify wait with timeout is not supported; timeout will be ignored"; // FIXME
|
||||||
|
|
||||||
if (useJspi()) {
|
|
||||||
qt_jspi_suspend_js();
|
|
||||||
} else {
|
|
||||||
bool didSuspend = qt_asyncify_suspend();
|
bool didSuspend = qt_asyncify_suspend();
|
||||||
if (!didSuspend) {
|
if (!didSuspend) {
|
||||||
qWarning("QEventDispatcherWasm: current thread is already suspended; could not asyncify wait for events");
|
qWarning("QEventDispatcherWasm: current thread is already suspended; could not asyncify wait for events");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
qWarning("QEventLoop::WaitForMoreEvents is not supported on the main thread without asyncify");
|
qWarning("QEventLoop::WaitForMoreEvents is not supported on the main thread without asyncify");
|
||||||
@ -559,21 +487,9 @@ bool QEventDispatcherWasm::wakeEventDispatcherThread()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Q_ASSERT(isMainThreadEventDispatcher());
|
Q_ASSERT(isMainThreadEventDispatcher());
|
||||||
if (useJspi()) {
|
|
||||||
|
|
||||||
#if QT_CONFIG(thread)
|
|
||||||
return qstdweb::runTaskOnMainThread<bool>(
|
|
||||||
[]() { return qt_jspi_can_resume_js() && qt_jspi_resume_js(); }, &g_proxyingQueue);
|
|
||||||
#else
|
|
||||||
return qstdweb::runTaskOnMainThread<bool>(
|
|
||||||
[]() { return qt_jspi_can_resume_js() && qt_jspi_resume_js(); });
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (!g_is_asyncify_suspended)
|
if (!g_is_asyncify_suspended)
|
||||||
return false;
|
return false;
|
||||||
runOnMainThread([]() { qt_asyncify_resume(); });
|
runOnMainThread([]() { qt_asyncify_resume(); });
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user