From 78f05c0a6514ca084051f16498513033dacb14aa Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Wed, 2 Oct 2013 23:25:44 +0200 Subject: toolkit: avoid deadlock in UnoControl::setDesignMode() Avoid deadlock by disposing the accesibility context without the Mutex locked, since it will eventually try to acquire the SolarMutex... Thread 1 in UnoControl::getPosSize() calling from sdr::contact::ControlHolder::getPosSize() Thread 2 calling from UnoControl::setDesignMode() trying to get SolarMutex in VCLXWindow::disposing() Change-Id: I7d0ffe4fa0f8cd0c48e9b9b5e923ce229f97ca57 --- toolkit/source/controls/unocontrol.cxx | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'toolkit') diff --git a/toolkit/source/controls/unocontrol.cxx b/toolkit/source/controls/unocontrol.cxx index 49333fcf4483..5d6700e1d6dc 100644 --- a/toolkit/source/controls/unocontrol.cxx +++ b/toolkit/source/controls/unocontrol.cxx @@ -333,12 +333,11 @@ void UnoControl::updateFromModel() // XTypeProvider IMPL_IMPLEMENTATION_ID( UnoControl ) -void UnoControl::disposeAccessibleContext() +void +UnoControl::DisposeAccessibleContext(Reference const& xContextComp) { - Reference< XComponent > xContextComp( maAccessibleContext.get(), UNO_QUERY ); - if ( xContextComp.is() ) + if (xContextComp.is()) { - maAccessibleContext = NULL; try { xContextComp->removeEventListener( this ); @@ -354,6 +353,7 @@ void UnoControl::disposeAccessibleContext() void UnoControl::dispose( ) throw(RuntimeException) { Reference< XWindowPeer > xPeer; + Reference xAccessibleComp; { ::osl::MutexGuard aGuard( GetMutex() ); if( mbDisposePeer ) @@ -361,14 +361,16 @@ void UnoControl::dispose( ) throw(RuntimeException) xPeer = mxPeer; } setPeer( NULL ); + xAccessibleComp.set(maAccessibleContext, UNO_QUERY); + maAccessibleContext.clear(); } if( xPeer.is() ) { xPeer->dispose(); } - // dispose and release our AccessibleContext - disposeAccessibleContext(); + // dispose our AccessibleContext - without Mutex locked + DisposeAccessibleContext(xAccessibleComp); EventObject aDisposeEvent; aDisposeEvent.Source = static_cast< XAggregation* >( this ); @@ -1382,6 +1384,7 @@ void UnoControl::setDesignMode( sal_Bool bOn ) throw(RuntimeException) ModeChangeEvent aModeChangeEvent; Reference< XWindow > xWindow; + Reference xAccessibleComp; { ::osl::MutexGuard aGuard( GetMutex() ); if ( bOn == mbDesignMode ) @@ -1390,15 +1393,19 @@ void UnoControl::setDesignMode( sal_Bool bOn ) throw(RuntimeException) // remember this mbDesignMode = bOn; xWindow = xWindow.query( getPeer() ); - // dispose our current AccessibleContext, if we have one - // (changing the design mode implies having a new implementation for this context, - // so the old one must be declared DEFUNC) - disposeAccessibleContext(); + + xAccessibleComp.set(maAccessibleContext, UNO_QUERY); + maAccessibleContext.clear(); aModeChangeEvent.Source = *this; aModeChangeEvent.NewMode = mbDesignMode ? OUString("design") : OUString("alive" ); } + // dispose current AccessibleContext, if we have one - without Mutex lock + // (changing the design mode implies having a new implementation for this context, + // so the old one must be declared DEFUNC) + DisposeAccessibleContext(xAccessibleComp); + // ajust the visibility of our window if ( xWindow.is() ) xWindow->setVisible( !bOn ); -- cgit