summaryrefslogtreecommitdiff
path: root/toolkit
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2013-10-02 23:25:44 +0200
committerMichael Stahl <mstahl@redhat.com>2013-10-02 23:52:44 +0200
commit78f05c0a6514ca084051f16498513033dacb14aa (patch)
treea6d26de1ea3fb137cd2e1d87b8b085a4a33c4874 /toolkit
parentcf88ebc1f7d358a1dcd9e5b49026194e05916896 (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
Diffstat (limited to 'toolkit')
-rw-r--r--toolkit/source/controls/unocontrol.cxx27
1 files changed, 17 insertions, 10 deletions
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 );