[Libreoffice-commits] core.git: vcl/win
Stephan Bergmann (via logerrit)
logerrit at kemper.freedesktop.org
Thu Sep 24 16:04:25 UTC 2020
vcl/win/app/salinst.cxx | 35 +++++++++++++++++++++++++++++++----
1 file changed, 31 insertions(+), 4 deletions(-)
New commits:
commit 9771e61666455c969de751e4d8f27c1c160780e1
Author: Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Thu Sep 24 13:27:17 2020 +0200
Commit: Stephan Bergmann <sbergman at redhat.com>
CommitDate: Thu Sep 24 18:03:40 2020 +0200
Revert "Directly acquire m_aMutex, instead of looping on m_condition.wait()"
This reverts commit e9a16702ba025ca340bcded4fda37235d22410a1. My understanding
that the code was pointless was apparently wrong (the relevant part being hidden
in m_condition.wait() internally doing the call to MsgWaitForMultipleObjects;
I've improved the relevant comment now). (And my fears that the code using
osl::Condition might be broken by design were hopefully unfounded.)
Change-Id: Icb244ec9df8a2b0dacf115700ed850d471446f3a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103310
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
Tested-by: Jenkins
diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx
index 3af78712b1d2..476b6350147a 100644
--- a/vcl/win/app/salinst.cxx
+++ b/vcl/win/app/salinst.cxx
@@ -99,6 +99,9 @@ static LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPA
class SalYieldMutex : public comphelper::SolarMutex
{
+public: // for ImplSalYield() and ImplSalYieldMutexAcquireWithWait()
+ osl::Condition m_condition; /// for MsgWaitForMultipleObjects()
+
protected:
virtual void doAcquire( sal_uInt32 nLockCount ) override;
virtual sal_uInt32 doRelease( bool bUnlockAll ) override;
@@ -135,11 +138,31 @@ void SalYieldMutex::BeforeReleaseHandler()
void SalYieldMutex::doAcquire( sal_uInt32 nLockCount )
{
WinSalInstance* pInst = GetSalData()->mpInstance;
- if ( pInst && pInst->IsMainThread() && pInst->m_nNoYieldLock )
+ if ( pInst && pInst->IsMainThread() )
{
- return;
+ if ( pInst->m_nNoYieldLock )
+ return;
+ // tdf#96887 If this is the main thread, then we must wait for two things:
+ // - the yield mutex being unlocked
+ // - SendMessage() being triggered
+ // This can nicely be done using MsgWaitForMultipleObjects, which is called in
+ // m_condition.wait(). The 2nd one is
+ // needed because if we don't reschedule, then we create deadlocks if a
+ // Window's create/destroy is called via SendMessage() from another thread.
+ // Have a look at the osl_waitCondition implementation for more info.
+ do {
+ // reset condition *before* acquiring!
+ m_condition.reset();
+ if (m_aMutex.tryToAcquire())
+ break;
+ // wait for SalYieldMutex::release() to set the condition
+ osl::Condition::Result res = m_condition.wait();
+ assert(osl::Condition::Result::result_ok == res);
+ }
+ while ( true );
}
- m_aMutex.acquire();
+ else
+ m_aMutex.acquire();
++m_nCount;
--nLockCount;
@@ -152,7 +175,11 @@ sal_uInt32 SalYieldMutex::doRelease( const bool bUnlockAll )
if ( pInst && pInst->m_nNoYieldLock && pInst->IsMainThread() )
return 1;
- return comphelper::SolarMutex::doRelease( bUnlockAll );
+ sal_uInt32 nCount = comphelper::SolarMutex::doRelease( bUnlockAll );
+ // wake up ImplSalYieldMutexAcquireWithWait() after release
+ if ( 0 == m_nCount )
+ m_condition.set();
+ return nCount;
}
bool SalYieldMutex::tryToAcquire()
More information about the Libreoffice-commits
mailing list