summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qeventdispatcher_wasm.cpp74
-rw-r--r--src/corelib/kernel/qeventdispatcher_wasm_p.h1
-rw-r--r--src/corelib/platform/wasm/qstdweb_p.h42
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