summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <stephan.bergmann@allotropia.de>2024-08-16 15:02:15 +0200
committerStephan Bergmann <stephan.bergmann@allotropia.de>2024-08-18 15:10:00 +0200
commit50cd19debbd3f94df0fc4b370f6f6e69d4a1e085 (patch)
tree8da269eb47af6f3f8bcbbc3eee9526b2e2dbef6b
parent38b9d5e86dcab74288163bb8c6ad798e93e3bedf (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.idl1
-rw-r--r--unotest/Library_embindtest.mk2
-rw-r--r--unotest/source/embindtest/embindtest.cxx29
-rw-r--r--unotest/source/embindtest/embindtest.js1
-rw-r--r--vcl/inc/salinst.hxx2
-rw-r--r--vcl/qt5/QtInstance.cxx11
-rw-r--r--vcl/source/app/salvtables.cxx2
-rw-r--r--vcl/source/app/svapp.cxx2
-rw-r--r--vcl/source/app/svmain.cxx2
-rw-r--r--vcl/win/gdi/salprn.cxx2
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,