diff options
author | Michael Stahl <mstahl@redhat.com> | 2015-06-26 13:01:51 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2015-06-26 23:14:46 +0200 |
commit | 482c52e91fe41a52e68827e9bf64a9736427d517 (patch) | |
tree | e71ffbc0d540833494e326f4bb03d10e21e97a14 /vcl/osx | |
parent | c1e12b15e55a82f062960f40921e0c97afda2078 (diff) |
vcl: fix Win32 deadlocks from SolarMutexReleaser
To create and destroy thread-affine Win32 Windows and DCs, non-main
threads SendMessage() special messages like SAL_MSG_CREATEFRAME.
The main thread must handle these messages and return the result to
un-block the other thread.
This works fine as long as the main thread is in its message loop anyway
and blocked on GetMessage(); however if the main blocks trying to acquire
the SolarMutex that is held by the sending thread, deadlock results.
In order to work around this, there is some peculiar code in
ImplSalYieldMutexAcquireWithWait() to avoid blocking the main thread on
mpSalYieldMutex but instead block in GetMessage().
The crucial detail is that GetMessage() will immediately dispatch any
message sent via SendMessage(), which avoids the deadlock.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms644936.aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/ms644927.aspx
Most of the Win32 WndProc that acquire SolarMutex do so via
ImplSalYieldMutexAcquireWithWait(), but the main thread may also
temporarily drop SolarMutex and re-aquire it with the questionable
SolarMutexReleaser hack, which calls ImplSalAcquireYieldMutex()
instead, which blocks on mpSalYieldMutex.
Fix SolarMutexReleaser to call a new function
Application::ReAcquireSolarMutex() that does the right thing here:
acquire SolarMutex via ImplSalYieldMutexAcquireWithWait().
It turns out that this problem was already fixed before in commit
6a8fd4c76a969ac98d1aff91ff7442f43aee0006 but the problem was
insufficiently documented in the commit and it introduced the bug
that Application::Reschedule() was called without having the SolarMutex
locked, which caused timers to run without SolarMutex, so the commit
was reverted in 1ef1781390845d03b6e1518bbac81b818be62f3d.
Change-Id: I60aae555a9ee3c6390f584feddbc6b3cb7de0250
Diffstat (limited to 'vcl/osx')
-rw-r--r-- | vcl/osx/salinst.cxx | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx index 0d6c710f46ca..f05b15a68603 100644 --- a/vcl/osx/salinst.cxx +++ b/vcl/osx/salinst.cxx @@ -559,8 +559,10 @@ class ReleasePoolHolder ~ReleasePoolHolder() { [mpPool release]; } }; -void AquaSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) +void AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong const nReleased) { + (void) nReleased; + assert(nReleased == 0); // not implemented // ensure that the per thread autorelease pool is top level and // will therefore not be destroyed by cocoa implicitly SalData::ensureThreadAutoreleasePool(); |