desktop/source/lib/init.cxx              |    4 ++--
 unotest/source/embindtest/embindtest.cxx |    2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

New commits:
commit 85933f0473e67b55b94f46320683dd9516801a62
Author:     Stephan Bergmann <stephan.bergm...@collabora.com>
AuthorDate: Tue Aug 5 20:53:22 2025 +0200
Commit:     Stephan Bergmann <stephan.bergm...@collabora.com>
CommitDate: Wed Aug 6 07:55:38 2025 +0200

    Skip dubious LOKit SolarMutex acquire for Emscripten
    
    Otherwise, running the embindtest code in a LOKit-based scenario 
(analogously to
    how it is run under certain circumstances via
    
      --post-js $(SRCDIR)/unotest/source/embindtest/embindtest.js
    
    in desktop/Executable_soffice_bin.mk) would cause a deadlock when
    TestThread::execute (in unotest/source/embindtest/embindtest.cxx) calls
    
      SolarMutexGuard g;
    
    on that additional thread, but the main thread never released the SolarMutex
    because of that acquire in lo_runLoop.
    
    The code in lo_runLoop had originally been added with
    b693fb5cf154b177dd03184c789a4ef6b2aaa833 "We apparently need to drop the 
Solar
    Mutex when exiting lo_runLoop() on iOS" (curiously using explicit calls to
    acquire and release, instead of using an additional SolarMutexGuard; the
    difference being that a SolarMutexGuard would automatically be released 
upon an
    exception, which skips the explicit call to release), originally only for 
iOS,
    then extended to Android with 0abdf307eae9bca36b3bdc26199e208ae2c1b5fa 
"android:
    Unregistering in runLoop() is important even on Android", then extended to
    Emscripten with 1e421b30e2440f8a6e82ba4df1be3fb7c63e6996 "Attempt to add 
ifdefs
    for WASM (Emscripten) for LOKit-based code" for no apparent reason.
    
    I have no idea how the Android and iOS scenarios are meant to cope with
    soffice_main being called with SolarMutex being acquired twice, so that no 
other
    threads could ever acquire it (except thanks to temporary uses of
    SolarMutexReleaser, which might explain things).
    
    However, what happens in the Emscripten scenario is that executing 
soffice_main
    leads to a call to emscripten_set_main_loop_arg in SvpSalInstance::DoExecute
    (vcl/headless/svpinst.cxx), which quits by throwing an exception all the 
way to
    the JS event loop, so that in lo_runLoop the inner SolarMutexGuard 
automatically
    gets released, while the outer explicit call to release got skipped, 
leaving the
    SolarMutex locked forever on the main thread.
    
    As there is no apparent reason why the Emscripten scenario should have this
    double locking here (and the call to vcl::lok::unregisterPollCallbacks at 
the
    bottom of lo_runLoop would never be executed in the Emscripten scenario, 
anyway,
    thanks to the exception being thrown from emscripten_set_main_loop_arg), and
    1e421b30e2440f8a6e82ba4df1be3fb7c63e6996 "Attempt to add ifdefs for WASM
    (Emscripten) for LOKit-based code" maybe just added it in a blind 
copy/paste,
    lets just skip it.
    
    (And add a DBG_TESTNOTSOLARMUTEX to the embindtest code, to document that 
code's
    assumptions.)
    
    Change-Id: Ibae0d1d8b5f29f08d30829251ed2bb58413ea4e5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188973
    Reviewed-by: Stephan Bergmann <stephan.bergm...@collabora.com>
    Tested-by: Jenkins

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index efb019dcdb21..a4b63b1861df 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -7809,7 +7809,7 @@ static void lo_runLoop(LibreOfficeKit* /*pThis*/,
                        LibreOfficeKitWakeCallback pWakeCallback,
                        void* pData)
 {
-#if defined(IOS) || defined(ANDROID) || defined(__EMSCRIPTEN__)
+#if defined(IOS) || defined(ANDROID)
     Application::GetSolarMutex().acquire();
 #endif
 
@@ -7821,7 +7821,7 @@ static void lo_runLoop(LibreOfficeKit* /*pThis*/,
         Application::UpdateMainThread();
         soffice_main();
     }
-#if defined(IOS) || defined(ANDROID) || defined(__EMSCRIPTEN__)
+#if defined(IOS) || defined(ANDROID)
     vcl::lok::unregisterPollCallbacks();
     Application::ReleaseSolarMutex();
 #endif
diff --git a/unotest/source/embindtest/embindtest.cxx 
b/unotest/source/embindtest/embindtest.cxx
index 21d5e3542d4e..424c2f6d0a87 100644
--- a/unotest/source/embindtest/embindtest.cxx
+++ b/unotest/source/embindtest/embindtest.cxx
@@ -41,6 +41,7 @@
 #include <rtl/ustring.hxx>
 #include <sal/types.h>
 #include <salhelper/thread.hxx>
+#include <tools/debug.hxx>
 #include <uno/dispatcher.hxx>
 #include <uno/environment.h>
 #include <uno/environment.hxx>
@@ -949,6 +950,7 @@ class Test
 
     sal_Bool SAL_CALL testSolarMutex() override
     {
+        DBG_TESTNOTSOLARMUTEX();
         rtl::Reference t(new TestThread);
         t->launch();
         t->join();

Reply via email to