diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/corelib/kernel/qeventdispatcher_wasm.cpp | 74 | ||||
| -rw-r--r-- | src/corelib/kernel/qeventdispatcher_wasm_p.h | 1 | ||||
| -rw-r--r-- | src/corelib/platform/wasm/qstdweb_p.h | 42 |
3 files changed, 78 insertions, 39 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_wasm.cpp b/src/corelib/kernel/qeventdispatcher_wasm.cpp index 0de5c140699..25c707643ae 100644 --- a/src/corelib/kernel/qeventdispatcher_wasm.cpp +++ b/src/corelib/kernel/qeventdispatcher_wasm.cpp @@ -16,6 +16,12 @@ using namespace std::chrono_literals; +#if QT_CONFIG(thread) +#define PROXYING_QUEUE_PARAM , &g_proxyingQueue +#else +#define PROXYING_QUEUE_PARAM +#endif // QT_CONFIG(thread) + QT_BEGIN_NAMESPACE // using namespace emscripten; @@ -315,8 +321,10 @@ void QEventDispatcherWasm::registerSocketNotifier(QSocketNotifier *notifier) bool wasEmpty = g_socketNotifiers.empty(); g_socketNotifiers.insert({notifier->socket(), notifier}); - if (wasEmpty) - runOnMainThread([]{ setEmscriptenSocketCallbacks(); }); + if (wasEmpty) { + qstdweb::runTaskOnMainThread<void>([] { setEmscriptenSocketCallbacks(); } + PROXYING_QUEUE_PARAM); + } } void QEventDispatcherWasm::unregisterSocketNotifier(QSocketNotifier *notifier) @@ -331,8 +339,10 @@ void QEventDispatcherWasm::unregisterSocketNotifier(QSocketNotifier *notifier) } } - if (g_socketNotifiers.empty()) - runOnMainThread([]{ clearEmscriptenSocketCallbacks(); }); + if (g_socketNotifiers.empty()) { + qstdweb::runTaskOnMainThread<void>([] { clearEmscriptenSocketCallbacks(); } + PROXYING_QUEUE_PARAM); + } } void QEventDispatcherWasm::registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object) @@ -528,14 +538,16 @@ bool QEventDispatcherWasm::wakeEventDispatcherThread() if (useJspi()) { if (!qt_jspi_can_resume_js()) return false; - runOnMainThread([]{ qt_jspi_resume_js(); }); - return true; + return qstdweb::runTaskOnMainThread<bool>([]() { return qt_jspi_resume_js(); } + PROXYING_QUEUE_PARAM); } - if (g_is_asyncify_suspended) { - runOnMainThread([]{ qt_asyncify_resume(); }); - return true; - } - return false; + return g_is_asyncify_suspended + && qstdweb::runTaskOnMainThread<bool>( + [] { + qt_asyncify_resume(); + return true; + } + PROXYING_QUEUE_PARAM); } // Process event activation callbacks for the main thread event dispatcher. @@ -620,17 +632,19 @@ void QEventDispatcherWasm::updateNativeTimer() // Update the native timer for this thread/dispatcher. This must be // done on the main thread where we have access to native API. - runOnMainThread([this, maintainNativeTimer]() { - Q_ASSERT(emscripten_is_main_runtime_thread()); - - // "this" may have been deleted, or may be about to be deleted. - // Check if the pointer we have is still a valid event dispatcher, - // and keep the mutex locked while updating the native timer to - // prevent it from being deleted. - LOCK_GUARD(g_staticDataMutex); - if (isValidEventDispatcherPointer(this)) - maintainNativeTimer(); - }); + qstdweb::runTaskOnMainThread<void>( + [this, maintainNativeTimer]() { + Q_ASSERT(emscripten_is_main_runtime_thread()); + + // "this" may have been deleted, or may be about to be deleted. + // Check if the pointer we have is still a valid event dispatcher, + // and keep the mutex locked while updating the native timer to + // prevent it from being deleted. + LOCK_GUARD(g_staticDataMutex); + if (isValidEventDispatcherPointer(this)) + maintainNativeTimer(); + } + PROXYING_QUEUE_PARAM); } // Static timer activation callback. Must be called on the main thread @@ -896,22 +910,6 @@ void QEventDispatcherWasm::runAsync(std::function<void(void)> fn) trampoline(new std::function<void(void)>(fn)); } -// Runs a function on the main thread. The function runs synchronusly if -// the calling thread is then main thread. -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); - g_proxyingQueue.proxyAsync(g_mainThread, [context]{ - trampoline(context); - }); - return; - } -#endif - fn(); -} - // Runs a function on the main thread. The function always runs asynchronously, // also if the calling thread is the main thread. void QEventDispatcherWasm::runOnMainThreadAsync(std::function<void(void)> fn) diff --git a/src/corelib/kernel/qeventdispatcher_wasm_p.h b/src/corelib/kernel/qeventdispatcher_wasm_p.h index 8a9782a96f8..598e15dc6bb 100644 --- a/src/corelib/kernel/qeventdispatcher_wasm_p.h +++ b/src/corelib/kernel/qeventdispatcher_wasm_p.h @@ -89,7 +89,6 @@ private: static void run(std::function<void(void)> fn); static void runAsync(std::function<void(void)> fn); - static void runOnMainThread(std::function<void(void)> fn); static void runOnMainThreadAsync(std::function<void(void)> fn); static QEventDispatcherWasm *g_mainThreadEventDispatcher; diff --git a/src/corelib/platform/wasm/qstdweb_p.h b/src/corelib/platform/wasm/qstdweb_p.h index 94b99bb0d70..42e6a22381a 100644 --- a/src/corelib/platform/wasm/qstdweb_p.h +++ b/src/corelib/platform/wasm/qstdweb_p.h @@ -28,6 +28,11 @@ #include <string> #include <utility> +#if QT_CONFIG(thread) +#include <emscripten/proxying.h> +#include <emscripten/threading.h> +#endif // #if QT_CONFIG(thread) + QT_BEGIN_NAMESPACE class QMimeData; @@ -218,6 +223,43 @@ namespace qstdweb { Q_CORE_EXPORT std::shared_ptr<CancellationFlag> readDataTransfer(emscripten::val webObject, std::function<QVariant(QByteArray)> imageReader, std::function<void(std::unique_ptr<QMimeData>)> onDone); + +#if QT_CONFIG(thread) + template<class T> + T proxyCall(std::function<T()> task, emscripten::ProxyingQueue *queue) + { + T result; + queue->proxySync(emscripten_main_browser_thread_id(), + [task, result = &result]() { *result = task(); }); + return result; + } + + template<> + inline void proxyCall<void>(std::function<void()> task, emscripten::ProxyingQueue *queue) + { + queue->proxySync(emscripten_main_browser_thread_id(), task); + } + + template<class T> + T runTaskOnMainThread(std::function<T()> task, emscripten::ProxyingQueue *queue) + { + return emscripten_is_main_runtime_thread() ? task() : proxyCall<T>(std::move(task), queue); + } + + template<class T> + T runTaskOnMainThread(std::function<T()> task) + { + emscripten::ProxyingQueue singleUseQueue; + return runTaskOnMainThread<T>(task, &singleUseQueue); + } + +#else + template<class T> + T runTaskOnMainThread(std::function<T()> task) + { + return task(); + } +#endif // QT_CONFIG(thread) } QT_END_NAMESPACE |
