Kaydet (Commit) 78f05c0a authored tarafından Michael Stahl's avatar Michael Stahl

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
üst cf88ebc1
......@@ -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)
{
......
......@@ -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;
......
......@@ -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 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment