summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2023-06-13 12:30:44 +0200
committerMichael Stahl <michael.stahl@allotropia.de>2023-06-13 12:30:44 +0200
commit2b317048d72d39a9d64b2eb8055eef7045ad449a (patch)
treee173a829987e341c7fae225d6ba49f01f8df4557 /vcl
parentaf1e9f9b8726b84dc5c6e644ed317873dacbe1f5 (diff)
tdf#155794 vcl: handle WM_GETOBJECT without SolarMutex
SalFrameWndProc() handles WM_GETOBJECT by acquiring SolarMutex and calling ImplHandleGetObject(), which again acquires the SolarMutex inside Application::SetSettings(). This was introduced with commit db214684057e3ff2fa32d57c00507309dd6c24d6 due to thread-safety crashes but it turns out that it can be problematic. When loading a document on a non-main thread, WinSalFrame::SetTitle() calls SetWindowTextW which is equivalent to SendMessage(WM_SETTEXT), while holding SolarMutex, and if the main thread doesn't finish processing it then that's a deadlock. Typically Desktop::Main() has already created the mxAccessBridge, so ImplHandleGetObject() most likely doesn't need to do it, so just skip the Settings code there in case the SolarMutex is locked by another thread. In case the SolarMutex is locked by another thread, do an unsafe read of ImplGetSVData()->mxAccessBridge - this should work until ImplSVData is deleted, by which time no Windows should exist anymore that could be receiving messages. This fixes part of the problem, winaccessibility also needs to stop using SolarMutex. Change-Id: I62b027ad06d2c3eb06a5f64b052a4acd0908f79c
Diffstat (limited to 'vcl')
-rw-r--r--vcl/win/window/salframe.cxx48
1 files changed, 30 insertions, 18 deletions
diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx
index 4fb572fc19a9..ab6db6aa41b3 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -5280,27 +5280,40 @@ static void ImplHandleIMENotify( HWND hWnd, WPARAM wParam )
static bool
ImplHandleGetObject(HWND hWnd, LPARAM lParam, WPARAM wParam, LRESULT & nRet)
{
- // IA2 should be enabled automatically
- AllSettings aSettings = Application::GetSettings();
- MiscSettings aMisc = aSettings.GetMiscSettings();
- aMisc.SetEnableATToolSupport( true );
- aSettings.SetMiscSettings( aMisc );
- Application::SetSettings( aSettings );
+ uno::Reference<accessibility::XMSAAService> xMSAA;
+ if (ImplSalYieldMutexTryToAcquire())
+ {
+ // IA2 should be enabled automatically
+ AllSettings aSettings = Application::GetSettings();
+ MiscSettings aMisc = aSettings.GetMiscSettings();
+ aMisc.SetEnableATToolSupport( true );
+ aSettings.SetMiscSettings( aMisc );
+ Application::SetSettings( aSettings );
- if (!Application::GetSettings().GetMiscSettings().GetEnableATToolSupport())
- return false; // locked down somehow ?
+ if (!Application::GetSettings().GetMiscSettings().GetEnableATToolSupport())
+ return false; // locked down somehow ?
- ImplSVData* pSVData = ImplGetSVData();
+ ImplSVData* pSVData = ImplGetSVData();
- // Make sure to launch Accessibility only the following criteria are satisfied
- // to avoid RFT interrupts regular accessibility processing
- if ( !pSVData->mxAccessBridge.is() )
- {
- if( !InitAccessBridge() )
- return false;
+ // Make sure to launch Accessibility only the following criteria are satisfied
+ // to avoid RFT interrupts regular accessibility processing
+ if ( !pSVData->mxAccessBridge.is() )
+ {
+ if( !InitAccessBridge() )
+ return false;
+ }
+ xMSAA.set(pSVData->mxAccessBridge, uno::UNO_QUERY);
+ ImplSalYieldMutexRelease();
+ }
+ else
+ { // tdf#155794: access without locking: hopefully this should be fine
+ // as the bridge is typically inited in Desktop::Main() already and the
+ // WM_GETOBJECT is received only on the main thread and by the time in
+ // VCL shutdown when ImplSvData dies there should not be Windows any
+ // more that could receive messages.
+ xMSAA.set(ImplGetSVData()->mxAccessBridge, uno::UNO_QUERY);
}
- uno::Reference< accessibility::XMSAAService > xMSAA( pSVData->mxAccessBridge, uno::UNO_QUERY );
if ( xMSAA.is() )
{
sal_Int32 lParam32 = static_cast<sal_Int32>(lParam);
@@ -5831,12 +5844,11 @@ static LRESULT CALLBACK SalFrameWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LP
break;
case WM_GETOBJECT:
- ImplSalYieldMutexAcquireWithWait();
+ // tdf#155794: this must complete without taking SolarMutex
if ( ImplHandleGetObject( hWnd, lParam, wParam, nRet ) )
{
rDef = false;
}
- ImplSalYieldMutexRelease();
break;
case WM_APPCOMMAND: