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 #include #include +#include #include #include #include #include +#include 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 { sal_Bool SAL_CALL getBoolean() override { return true; } @@ -871,6 +891,15 @@ class Test : public cppu::WeakImplHelper 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 #include #include +#include #include #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && ENABLE_GSTREAMER_1_0 && QT5_HAVE_GOBJECT #include @@ -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(pOutBuffer) + pOutBuffer->mnDriverOffset; nRet = DocumentPropertiesW( hWnd, hPrn,