summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2013-08-27 21:43:48 +0200
committerFridrich Strba <fridrich@documentfoundation.org>2013-08-29 11:52:11 +0000
commit9888a00405dc320e12ca2fc12446b85572144795 (patch)
treeb146bd914f75b68625f75726ab00fa0fa5ef174c
parentea316c964a8e4405ccbfdd0f27b5e07ede2c5239 (diff)
rhbz#1001768: avoid deadlock in AccessibleEventNotifier
revokeClientNotifyDisposing(): drop the static lclMutex before calling pListeners->disposeAndClear(), which may want to acquire the SolarMutex and deadlock. Change-Id: Ib35fc7fad6596450a3b10d58d5193b9b55c575cb (cherry picked from commit cafff1bbc4effac74bbd2607fb83dd2547c8fa2e) Reviewed-on: https://gerrit.libreoffice.org/5659 Reviewed-by: Fridrich Strba <fridrich@documentfoundation.org> Tested-by: Fridrich Strba <fridrich@documentfoundation.org>
-rw-r--r--comphelper/source/misc/accessibleeventnotifier.cxx33
1 files changed, 19 insertions, 14 deletions
diff --git a/comphelper/source/misc/accessibleeventnotifier.cxx b/comphelper/source/misc/accessibleeventnotifier.cxx
index e6e88de215a0..14ac88c78448 100644
--- a/comphelper/source/misc/accessibleeventnotifier.cxx
+++ b/comphelper/source/misc/accessibleeventnotifier.cxx
@@ -133,29 +133,34 @@ namespace comphelper
void AccessibleEventNotifier::revokeClientNotifyDisposing( const TClientId _nClient,
const Reference< XInterface >& _rxEventSource ) SAL_THROW( ( ) )
{
- ::osl::MutexGuard aGuard( lclMutex::get() );
+ EventListeners * pListeners(0);
- ClientMap::iterator aClientPos;
- if ( !implLookupClient( _nClient, aClientPos ) )
- // already asserted in implLookupClient
- return;
+ {
+ // rhbz#1001768 drop the mutex before calling disposeAndClear
+ ::osl::MutexGuard aGuard( lclMutex::get() );
+
+ ClientMap::iterator aClientPos;
+ if (!implLookupClient(_nClient, aClientPos))
+ // already asserted in implLookupClient
+ return;
+
+ // notify the listeners
+ pListeners = aClientPos->second;
+
+ // we do not need the entry in the clients map anymore
+ // (do this before actually notifying, because some client
+ // implementations have re-entrance problems and call into
+ // revokeClient while we are notifying from here)
+ Clients::get().erase(aClientPos);
+ }
// notify the "disposing" event for this client
EventObject aDisposalEvent;
aDisposalEvent.Source = _rxEventSource;
- // notify the listeners
- EventListeners* pListeners = aClientPos->second;
-
- // we do not need the entry in the clients map anymore
- // (do this before actually notifying, because some client implementations have re-entrance
- // problems and call into revokeClient while we are notifying from hereing)
- Clients::get().erase( aClientPos );
-
// now really do the notification
pListeners->disposeAndClear( aDisposalEvent );
delete pListeners;
-
}
//---------------------------------------------------------------------