comphelper/source/misc/emscriptenthreading.cxx | 37 +++++++++---------------- include/comphelper/emscriptenthreading.hxx | 6 +--- solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk | 4 +- vcl/qt5/QtInstance.cxx | 7 ++-- vcl/source/app/scheduler.cxx | 12 +++++--- 5 files changed, 29 insertions(+), 37 deletions(-)
New commits: commit 7a84593ec130b41da35d98fe7d45a71706935909 Author: Stephan Bergmann <stephan.bergm...@allotropia.de> AuthorDate: Wed Feb 19 16:36:11 2025 +0100 Commit: Stephan Bergmann <stephan.bergm...@allotropia.de> CommitDate: Wed Feb 19 23:25:55 2025 +0100 Create Data on demand in comphelper::emscriptenthreading::getData ...and get rid of comphelper::emscriptenthreading::setUp. This will help with a potentially forthcoming change to move initUno in desktop/source/app/appinit.cxx to the eventHandlerThread (so code in both desktop and in vcl/qt5 would need the comphelper::emscriptenthreading::Data and it would be unclear which should call setUp). Change-Id: I157f80a450d8eeabd6d0317c881c6a9ea67fc59a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181908 Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de> Tested-by: Jenkins diff --git a/comphelper/source/misc/emscriptenthreading.cxx b/comphelper/source/misc/emscriptenthreading.cxx index b98c75a7b0a6..0cf905e86170 100644 --- a/comphelper/source/misc/emscriptenthreading.cxx +++ b/comphelper/source/misc/emscriptenthreading.cxx @@ -15,7 +15,6 @@ #if defined EMSCRIPTEN && ENABLE_QT6 && HAVE_EMSCRIPTEN_JSPI && !HAVE_EMSCRIPTEN_PROXY_TO_PTHREAD -#include <cassert> #include <mutex> #include <thread> @@ -25,29 +24,27 @@ std::mutex mutex; comphelper::emscriptenthreading::Data* data = nullptr; } -void comphelper::emscriptenthreading::setUp() +comphelper::emscriptenthreading::Data& comphelper::emscriptenthreading::getData() { std::scoped_lock g(mutex); - assert(data == nullptr); - data = new Data; - std::thread t([] { emscripten_exit_with_live_runtime(); }); - data->eventHandlerThread = t.native_handle(); - t.detach(); + if (data == nullptr) + { + data = new Data; + std::thread t([] { emscripten_exit_with_live_runtime(); }); + data->eventHandlerThread = t.native_handle(); + t.detach(); + } + return *data; } void comphelper::emscriptenthreading::tearDown() { std::scoped_lock g(mutex); - assert(data != nullptr); - delete data; - data = nullptr; -} - -comphelper::emscriptenthreading::Data& comphelper::emscriptenthreading::getData() -{ - std::scoped_lock g(mutex); - assert(data != nullptr); - return *data; + if (data != nullptr) + { + delete data; + data = nullptr; + } } #endif diff --git a/include/comphelper/emscriptenthreading.hxx b/include/comphelper/emscriptenthreading.hxx index 0e13af3af047..9d0abc273feb 100644 --- a/include/comphelper/emscriptenthreading.hxx +++ b/include/comphelper/emscriptenthreading.hxx @@ -28,11 +28,9 @@ struct Data std::thread::native_handle_type eventHandlerThread; }; -void setUp(); +Data& getData(); void tearDown(); - -Data& getData(); } #endif diff --git a/vcl/qt5/QtInstance.cxx b/vcl/qt5/QtInstance.cxx index 34a589bd4a57..01df658f2eb3 100644 --- a/vcl/qt5/QtInstance.cxx +++ b/vcl/qt5/QtInstance.cxx @@ -275,7 +275,6 @@ QtInstance::QtInstance(std::unique_ptr<QApplication>& pQApp) , m_pActivePopup(nullptr) { #if defined EMSCRIPTEN && ENABLE_QT6 && HAVE_EMSCRIPTEN_JSPI && !HAVE_EMSCRIPTEN_PROXY_TO_PTHREAD - comphelper::emscriptenthreading::setUp(); m_emscriptenThreadingData = &comphelper::emscriptenthreading::getData(); #endif commit 5e1973754a9b924b2d9362c6083866d2cf93b790 Author: Stephan Bergmann <stephan.bergm...@allotropia.de> AuthorDate: Tue Feb 18 11:24:43 2025 +0100 Commit: Stephan Bergmann <stephan.bergm...@allotropia.de> CommitDate: Wed Feb 19 23:25:42 2025 +0100 Redesign comphelper::emscriptenthreading::Data::eventHandlerThread Instead of being a thread that keeps blocking in C++ emscripten::ProxyingQueue::execute(), make it a thread that immediately goes back to the browser event loop via emscripten_exit_with_live_runtime(). (Which will eventually allow setupMainChannel from desktop/source/app/appinit.cxx to run on that thread and receive the "LOWA-channel" JS message event.) The thread is detached now and no longer joined in comphelper::emscriptenthreading::tearDown, but that was mostly academic anyway (as LOWA doesn't terminate in the traditional sense, and just stops when you close its browser tab). Change-Id: I32270cfc602549cf26b99c6f66811b3aca5ea5c0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181907 Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de> Tested-by: Jenkins diff --git a/comphelper/source/misc/emscriptenthreading.cxx b/comphelper/source/misc/emscriptenthreading.cxx index 622e8abb7408..b98c75a7b0a6 100644 --- a/comphelper/source/misc/emscriptenthreading.cxx +++ b/comphelper/source/misc/emscriptenthreading.cxx @@ -17,7 +17,6 @@ #include <cassert> #include <mutex> -#include <stop_token> #include <thread> namespace @@ -31,20 +30,15 @@ void comphelper::emscriptenthreading::setUp() std::scoped_lock g(mutex); assert(data == nullptr); data = new Data; - data->eventHandlerThread = std::jthread([](std::stop_token token) { - while (!token.stop_requested()) - { - data->proxyingQueue.execute(); - } - }); + std::thread t([] { emscripten_exit_with_live_runtime(); }); + data->eventHandlerThread = t.native_handle(); + t.detach(); } void comphelper::emscriptenthreading::tearDown() { std::scoped_lock g(mutex); assert(data != nullptr); - data->eventHandlerThread.request_stop(); - data->eventHandlerThread.join(); delete data; data = nullptr; } diff --git a/include/comphelper/emscriptenthreading.hxx b/include/comphelper/emscriptenthreading.hxx index 6f1b9306caa5..0e13af3af047 100644 --- a/include/comphelper/emscriptenthreading.hxx +++ b/include/comphelper/emscriptenthreading.hxx @@ -25,7 +25,7 @@ namespace comphelper::emscriptenthreading struct Data { emscripten::ProxyingQueue proxyingQueue; - std::jthread eventHandlerThread; + std::thread::native_handle_type eventHandlerThread; }; void setUp(); diff --git a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk index d5bb63ac1e89..c629c32f16ab 100644 --- a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk +++ b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk @@ -58,8 +58,8 @@ endif gb_LinkTarget_LDFLAGS += $(gb_EMSCRIPTEN_LDFLAGS) $(gb_EMSCRIPTEN_CPPFLAGS) \ $(gb_EMSCRIPTEN_EXCEPT) -sEXPORT_EXCEPTION_HANDLING_HELPERS -# Depending on emsdk version being used, enable e.g. std::jthread and std::stop_token used by some -# build configurations: +# Depending on emsdk version being used, might enable standard library features that would otherwise +# be hidden: gb_LinkTarget_CXXFLAGS += -fexperimental-library ifeq ($(ENABLE_OPTIMIZED),TRUE) diff --git a/vcl/qt5/QtInstance.cxx b/vcl/qt5/QtInstance.cxx index fc20ecc9e11c..34a589bd4a57 100644 --- a/vcl/qt5/QtInstance.cxx +++ b/vcl/qt5/QtInstance.cxx @@ -207,7 +207,7 @@ void QtInstance::RunInMainThread(std::function<void()> func) return; } #if defined EMSCRIPTEN && ENABLE_QT6 && HAVE_EMSCRIPTEN_JSPI && !HAVE_EMSCRIPTEN_PROXY_TO_PTHREAD - if (pthread_self() == m_emscriptenThreadingData->eventHandlerThread.native_handle()) + if (pthread_self() == m_emscriptenThreadingData->eventHandlerThread) { EmscriptenLightweightRunInMainThread(func); return; @@ -492,7 +492,7 @@ bool QtInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) m_aWaitingYieldCond.set(); } #if defined EMSCRIPTEN && ENABLE_QT6 && HAVE_EMSCRIPTEN_JSPI && !HAVE_EMSCRIPTEN_PROXY_TO_PTHREAD - else if (pthread_self() == m_emscriptenThreadingData->eventHandlerThread.native_handle()) + else if (pthread_self() == m_emscriptenThreadingData->eventHandlerThread) { SolarMutexReleaser release; struct Args @@ -563,7 +563,7 @@ void QtInstance::ProcessEvent(SalUserEvent aEvent) SolarMutexReleaser release; (void)emscripten_promise_await( emscripten_proxy_promise(m_emscriptenThreadingData->proxyingQueue.queue, - m_emscriptenThreadingData->eventHandlerThread.native_handle(), + m_emscriptenThreadingData->eventHandlerThread, [](void* p) { auto& aEvent = *static_cast<SalUserEvent*>(p); SolarMutexGuard g; diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx index ae88dee55df2..2dcc14fe1988 100644 --- a/vcl/source/app/scheduler.cxx +++ b/vcl/source/app/scheduler.cxx @@ -559,10 +559,14 @@ void Scheduler::CallbackTaskScheduling() if (pTask->DecideTransferredExecution()) { auto & data = comphelper::emscriptenthreading::getData(); - data.proxyingQueue.proxyAsync(data.eventHandlerThread.native_handle(), [pTask] { - SolarMutexGuard g; - pTask->Invoke(); - }); + (void) emscripten_proxy_promise( + data.proxyingQueue.queue, data.eventHandlerThread, + [](void * p) { + auto const pTask = static_cast<Task *>(p); + SolarMutexGuard g; + pTask->Invoke(); + }, + pTask); } else {