diff options
author | Michael Stahl <mstahl@redhat.com> | 2013-08-27 21:43:48 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2013-08-28 14:47:33 +0200 |
commit | cafff1bbc4effac74bbd2607fb83dd2547c8fa2e (patch) | |
tree | c99e7b96ebfa561f049acbe5c62755b26ea2776f /comphelper | |
parent | 36e1de2239a92b3969925167dd52d37021fb99d8 (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
Diffstat (limited to 'comphelper')
-rw-r--r-- | comphelper/source/misc/accessibleeventnotifier.cxx | 33 |
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; - } //--------------------------------------------------------------------- |