diff options
author | Stephan Bergmann <stephan.bergmann@allotropia.de> | 2024-08-16 15:02:15 +0200 |
---|---|---|
committer | Stephan Bergmann <stephan.bergmann@allotropia.de> | 2024-08-18 15:10:00 +0200 |
commit | 50cd19debbd3f94df0fc4b370f6f6e69d4a1e085 (patch) | |
tree | 8da269eb47af6f3f8bcbbc3eee9526b2e2dbef6b | |
parent | 38b9d5e86dcab74288163bb8c6ad798e93e3bedf (diff) |
Emscripten: Clean up SolarMutex
...before disappearing through the QApplication::exec() hole, or else the
SolarMutex would remain locked forever on the application's main thread.
This requires changing SalInstance::ReleaseYieldMutexAll() to
SalInstance::ReleaseYieldMutex(bool all). (Further recursive locking of the
SolarMutex via SolarMutexGuard instances that would be present on the call stack
leading up to the call to QApplication::exec() would be released during the
stack unwinding, so just undo the one acquiring done in InitVCL, not all of
them.)
Change-Id: I9ef57abb7da7f840999700e4eaeeefd2da784645
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171956
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
-rw-r--r-- | offapi/org/libreoffice/embindtest/XTest.idl | 1 | ||||
-rw-r--r-- | unotest/Library_embindtest.mk | 2 | ||||
-rw-r--r-- | unotest/source/embindtest/embindtest.cxx | 29 | ||||
-rw-r--r-- | unotest/source/embindtest/embindtest.js | 1 | ||||
-rw-r--r-- | vcl/inc/salinst.hxx | 2 | ||||
-rw-r--r-- | vcl/qt5/QtInstance.cxx | 11 | ||||
-rw-r--r-- | vcl/source/app/salvtables.cxx | 2 | ||||
-rw-r--r-- | vcl/source/app/svapp.cxx | 2 | ||||
-rw-r--r-- | vcl/source/app/svmain.cxx | 2 | ||||
-rw-r--r-- | vcl/win/gdi/salprn.cxx | 2 |
10 files changed, 49 insertions, 5 deletions
diff --git a/offapi/org/libreoffice/embindtest/XTest.idl b/offapi/org/libreoffice/embindtest/XTest.idl index 8d46c9e71d5a..276ce260a8e1 100644 --- a/offapi/org/libreoffice/embindtest/XTest.idl +++ b/offapi/org/libreoffice/embindtest/XTest.idl @@ -133,6 +133,7 @@ interface XTest { void passInterface([in] com::sun::star::uno::XInterface object); boolean checkAttributes([in] org::libreoffice::embindtest::XAttributes object); [attribute] string StringAttribute; + boolean testSolarMutex(); }; }; }; }; diff --git a/unotest/Library_embindtest.mk b/unotest/Library_embindtest.mk index e71fedc069dd..be18ca4d792d 100644 --- a/unotest/Library_embindtest.mk +++ b/unotest/Library_embindtest.mk @@ -19,6 +19,8 @@ $(eval $(call gb_Library_use_libraries,embindtest, \ cppu \ cppuhelper \ sal \ + salhelper \ + vcl \ )) $(eval $(call gb_Library_use_sdk_api,embindtest)) diff --git a/unotest/source/embindtest/embindtest.cxx b/unotest/source/embindtest/embindtest.cxx index 292c492a4478..60150dcd2ad9 100644 --- a/unotest/source/embindtest/embindtest.cxx +++ b/unotest/source/embindtest/embindtest.cxx @@ -35,10 +35,12 @@ #include <org/libreoffice/embindtest/XTest.hpp> #include <rtl/ustring.hxx> #include <sal/types.h> +#include <salhelper/thread.hxx> #include <uno/dispatcher.hxx> #include <uno/environment.h> #include <uno/environment.hxx> #include <uno/mapping.hxx> +#include <vcl/svapp.hxx> namespace com::sun::star::uno { @@ -47,6 +49,24 @@ class XComponentContext; namespace { +class TestThread : public salhelper::Thread +{ +public: + TestThread() + : Thread("embindtest") + { + } + + bool value = false; + +private: + void execute() override + { + SolarMutexGuard g; + value = true; + } +}; + class Test : public cppu::WeakImplHelper<org::libreoffice::embindtest::XTest> { sal_Bool SAL_CALL getBoolean() override { return true; } @@ -871,6 +891,15 @@ class Test : public cppu::WeakImplHelper<org::libreoffice::embindtest::XTest> void SAL_CALL setStringAttribute(OUString const& value) override { stringAttribute_ = value; } + sal_Bool SAL_CALL testSolarMutex() override + { + TestThread t; + t.launch(); + t.join(); + SolarMutexGuard g; + return t.value; + } + OUString stringAttribute_ = u"hä"_ustr; }; diff --git a/unotest/source/embindtest/embindtest.js b/unotest/source/embindtest/embindtest.js index 2242e5f81a8f..f75653a897cf 100644 --- a/unotest/source/embindtest/embindtest.js +++ b/unotest/source/embindtest/embindtest.js @@ -901,6 +901,7 @@ Module.uno_init.then(function() { console.assert(test.StringAttribute === 'hä'); test.StringAttribute = 'foo'; console.assert(test.StringAttribute === 'foo'); + console.assert(test.testSolarMutex()); const args = new Module.uno_Sequence_any( [new Module.uno_Any(Module.uno_Type.Interface('com.sun.star.uno.XInterface'), test)]); diff --git a/vcl/inc/salinst.hxx b/vcl/inc/salinst.hxx index 380ee2ce202e..1fbe86285054 100644 --- a/vcl/inc/salinst.hxx +++ b/vcl/inc/salinst.hxx @@ -137,7 +137,7 @@ public: // YieldMutex comphelper::SolarMutex* GetYieldMutex(); - sal_uInt32 ReleaseYieldMutexAll(); + sal_uInt32 ReleaseYieldMutex(bool all); void AcquireYieldMutex(sal_uInt32 nCount = 1); // return true, if the current thread is the main thread diff --git a/vcl/qt5/QtInstance.cxx b/vcl/qt5/QtInstance.cxx index 6872fb0fe1a3..dfcf0c2c4f08 100644 --- a/vcl/qt5/QtInstance.cxx +++ b/vcl/qt5/QtInstance.cxx @@ -55,6 +55,7 @@ #include <vcl/stdtext.hxx> #include <vcl/sysdata.hxx> #include <sal/log.hxx> +#include <o3tl/unreachable.hxx> #include <osl/process.h> #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && ENABLE_GSTREAMER_1_0 && QT5_HAVE_GOBJECT #include <unx/gstsink.hxx> @@ -769,7 +770,17 @@ bool QtInstance::DoExecute(int& nExitCode) { const bool bIsOnSystemEventLoop = Application::IsOnSystemEventLoop(); if (bIsOnSystemEventLoop) + { +#if defined EMSCRIPTEN + // For Emscripten, QApplication::exec() will unwind the stack by throwing a JavaScript + // exception, so we need to manually undo the call of AcquireYieldMutex() done in InitVCL: + ImplGetSVData()->mpDefInst->ReleaseYieldMutex(false); +#endif nExitCode = QApplication::exec(); +#if defined EMSCRIPTEN + O3TL_UNREACHABLE; +#endif + } return bIsOnSystemEventLoop; } diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 7e2a81f2cef4..7e18d15c470e 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -141,7 +141,7 @@ SalInstance::~SalInstance() {} comphelper::SolarMutex* SalInstance::GetYieldMutex() { return m_pYieldMutex.get(); } -sal_uInt32 SalInstance::ReleaseYieldMutexAll() { return m_pYieldMutex->release(true); } +sal_uInt32 SalInstance::ReleaseYieldMutex(bool all) { return m_pYieldMutex->release(all); } void SalInstance::AcquireYieldMutex(sal_uInt32 nCount) { m_pYieldMutex->acquire(nCount); } diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index 458da9d8c251..debd5ec920ff 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -499,7 +499,7 @@ bool Application::IsMainThread() sal_uInt32 Application::ReleaseSolarMutex() { ImplSVData* pSVData = ImplGetSVData(); - return pSVData->mpDefInst->ReleaseYieldMutexAll(); + return pSVData->mpDefInst->ReleaseYieldMutex(true); } void Application::AcquireSolarMutex( sal_uInt32 nCount ) diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx index f046755863f1..fd5ea7b3ef0b 100644 --- a/vcl/source/app/svmain.cxx +++ b/vcl/source/app/svmain.cxx @@ -624,7 +624,7 @@ void DeInitVCL() // Deinit Sal if (pSVData->mpDefInst) { - pSVData->mpDefInst->ReleaseYieldMutexAll(); + pSVData->mpDefInst->ReleaseYieldMutex(true); DestroySalInstance( pSVData->mpDefInst ); pSVData->mpDefInst = nullptr; } diff --git a/vcl/win/gdi/salprn.cxx b/vcl/win/gdi/salprn.cxx index b43c59e27473..393c8c7b1f3a 100644 --- a/vcl/win/gdi/salprn.cxx +++ b/vcl/win/gdi/salprn.cxx @@ -382,7 +382,7 @@ static bool ImplUpdateSalJobSetup( WinSalInfoPrinter const * pPrinter, ImplJobSe sal_uInt32 nMutexCount = 0; WinSalInstance* pInst = GetSalData()->mpInstance; if ( pInst && pVisibleDlgParent ) - nMutexCount = pInst->ReleaseYieldMutexAll(); + nMutexCount = pInst->ReleaseYieldMutex(true); BYTE* pOutDevMode = reinterpret_cast<BYTE*>(pOutBuffer) + pOutBuffer->mnDriverOffset; nRet = DocumentPropertiesW( hWnd, hPrn, |