diff options
author | Michael Stahl <mstahl@redhat.com> | 2013-10-02 23:25:44 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2013-10-02 23:52:44 +0200 |
commit | 78f05c0a6514ca084051f16498513033dacb14aa (patch) | |
tree | a6d26de1ea3fb137cd2e1d87b8b085a4a33c4874 | |
parent | cf88ebc1f7d358a1dcd9e5b49026194e05916896 (diff) |
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
-rw-r--r-- | include/toolkit/controls/unocontrol.hxx | 3 | ||||
-rw-r--r-- | svx/source/fmcomp/fmgridif.cxx | 4 | ||||
-rw-r--r-- | toolkit/source/controls/unocontrol.cxx | 27 |
3 files changed, 22 insertions, 12 deletions
diff --git a/include/toolkit/controls/unocontrol.hxx b/include/toolkit/controls/unocontrol.hxx index 66651666e29f..15aa918abb45 100644 --- a/include/toolkit/controls/unocontrol.hxx +++ b/include/toolkit/controls/unocontrol.hxx @@ -124,7 +124,8 @@ protected: void ImplLockPropertyChangeNotification( const OUString& rPropertyName, bool bLock ); void ImplLockPropertyChangeNotifications( const ::com::sun::star::uno::Sequence< OUString >& rPropertyNames, bool bLock ); - void disposeAccessibleContext(); + void DisposeAccessibleContext(::com::sun::star::uno::Reference< + ::com::sun::star::lang::XComponent> const& xContext); inline void setPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& _xPeer) { diff --git a/svx/source/fmcomp/fmgridif.cxx b/svx/source/fmcomp/fmgridif.cxx index 8d6e0752645d..358328bfc844 100644 --- a/svx/source/fmcomp/fmgridif.cxx +++ b/svx/source/fmcomp/fmgridif.cxx @@ -787,7 +787,9 @@ void SAL_CALL FmXGridControl::setDesignMode(sal_Bool bOn) throw( RuntimeExceptio // 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(); + DisposeAccessibleContext( + Reference<XComponent>(maAccessibleContext, UNO_QUERY)); + maAccessibleContext.clear(); // prepare firing an event aModeChangeEvent.Source = *this; 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<XComponent> 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<XComponent> 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<XComponent> 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 ); |