summaryrefslogtreecommitdiff
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
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
-rw-r--r--include/toolkit/controls/unocontrol.hxx3
-rw-r--r--svx/source/fmcomp/fmgridif.cxx4
-rw-r--r--toolkit/source/controls/unocontrol.cxx27
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 );