wasm: use emscripten::ProxyingQueue
Use ProxyingQueue for proxing calls from secondary threads to the main thread. This replaces the previous usage of the private emscripten_async_run...() API. Keep the existing "trampoline" which in addition proxies using a JavaScript zero timer. This makes sure that the proxied call is made with a clean stack, and not e.g. while the main thread is waiting on a mutex. Change-Id: I66cfdc2cf4bc733b1732973677c2ae46d85c8e7c Reviewed-by: Mikołaj Boc <Mikolaj.Boc@qt.io>
This commit is contained in:
parent
55568b8c62
commit
50057fec93
@ -116,6 +116,8 @@ Q_CONSTINIT QEventDispatcherWasm *QEventDispatcherWasm::g_mainThreadEventDispatc
|
||||
#if QT_CONFIG(thread)
|
||||
Q_CONSTINIT QVector<QEventDispatcherWasm *> QEventDispatcherWasm::g_secondaryThreadEventDispatchers;
|
||||
Q_CONSTINIT std::mutex QEventDispatcherWasm::g_staticDataMutex;
|
||||
emscripten::ProxyingQueue QEventDispatcherWasm::g_proxyingQueue;
|
||||
pthread_t QEventDispatcherWasm::g_mainThread;
|
||||
#endif
|
||||
// ### dynamic initialization:
|
||||
std::multimap<int, QSocketNotifier *> QEventDispatcherWasm::g_socketNotifiers;
|
||||
@ -144,6 +146,9 @@ QEventDispatcherWasm::QEventDispatcherWasm()
|
||||
// dispatchers so we set a global pointer to it.
|
||||
Q_ASSERT(g_mainThreadEventDispatcher == nullptr);
|
||||
g_mainThreadEventDispatcher = this;
|
||||
#if QT_CONFIG(thread)
|
||||
g_mainThread = pthread_self();
|
||||
#endif
|
||||
} else {
|
||||
#if QT_CONFIG(thread)
|
||||
std::lock_guard<std::mutex> lock(g_staticDataMutex);
|
||||
@ -818,7 +823,9 @@ void QEventDispatcherWasm::runOnMainThread(std::function<void(void)> fn)
|
||||
#if QT_CONFIG(thread)
|
||||
if (!emscripten_is_main_runtime_thread()) {
|
||||
void *context = new std::function<void(void)>(fn);
|
||||
emscripten_async_run_in_main_runtime_thread_(EM_FUNC_SIG_VI, reinterpret_cast<void *>(trampoline), context);
|
||||
g_proxyingQueue.proxyAsync(g_mainThread, [context]{
|
||||
trampoline(context);
|
||||
});
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -832,7 +839,9 @@ void QEventDispatcherWasm::runOnMainThreadAsync(std::function<void(void)> fn)
|
||||
void *context = new std::function<void(void)>(fn);
|
||||
#if QT_CONFIG(thread)
|
||||
if (!emscripten_is_main_runtime_thread()) {
|
||||
emscripten_async_run_in_main_runtime_thread_(EM_FUNC_SIG_VI, reinterpret_cast<void *>(trampoline), context);
|
||||
g_proxyingQueue.proxyAsync(g_mainThread, [context]{
|
||||
trampoline(context);
|
||||
});
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
|
||||
#include <emscripten/proxying.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcEventDispatcher);
|
||||
@ -106,6 +108,8 @@ private:
|
||||
|
||||
static QVector<QEventDispatcherWasm *> g_secondaryThreadEventDispatchers;
|
||||
static std::mutex g_staticDataMutex;
|
||||
static emscripten::ProxyingQueue g_proxyingQueue;
|
||||
static pthread_t g_mainThread;
|
||||
|
||||
// Note on mutex usage: the global g_staticDataMutex protects the global (g_ prefixed) data,
|
||||
// while the per eventdispatcher m_mutex protects the state accociated with blocking and waking
|
||||
|
Loading…
x
Reference in New Issue
Block a user