Index: source/Core/Broadcaster.cpp =================================================================== --- source/Core/Broadcaster.cpp +++ source/Core/Broadcaster.cpp @@ -57,17 +57,21 @@ void Broadcaster::Clear() { - Mutex::Locker listeners_locker(m_listeners_mutex); + collection old_listeners; + { + Mutex::Locker listeners_locker(m_listeners_mutex); + // Move the old listeners out of the way, so we can process them without holding the + // mutex. + old_listeners.swap(m_listeners); + } // Make sure the listener forgets about this broadcaster. We do // this in the broadcaster in case the broadcaster object initiates // the removal. - collection::iterator pos, end = m_listeners.end(); - for (pos = m_listeners.begin(); pos != end; ++pos) + collection::iterator pos, end = old_listeners.end(); + for (pos = old_listeners.begin(); pos != end; ++pos) pos->first->BroadcasterWillDestruct (this); - - m_listeners.clear(); } const ConstString & Broadcaster::GetBroadcasterName () Index: source/Core/Listener.cpp =================================================================== --- source/Core/Listener.cpp +++ source/Core/Listener.cpp @@ -57,15 +57,20 @@ void Listener::Clear() { - Mutex::Locker locker(m_broadcasters_mutex); - broadcaster_collection::iterator pos, end = m_broadcasters.end(); - for (pos = m_broadcasters.begin(); pos != end; ++pos) + broadcaster_collection old_broadcasters; + { + Mutex::Locker locker(m_broadcasters_mutex); + // Move the old broadcasters out of the way, so we can process them without holding the + // mutex. + old_broadcasters.swap(m_broadcasters); + m_cond_wait.SetValue (false, eBroadcastNever); + Mutex::Locker event_locker(m_events_mutex); + m_events.clear(); + } + + broadcaster_collection::iterator pos, end = old_broadcasters.end(); + for (pos = old_broadcasters.begin(); pos != end; ++pos) pos->first->RemoveListener (this, pos->second.event_mask); - m_broadcasters.clear(); - m_cond_wait.SetValue (false, eBroadcastNever); - m_broadcasters.clear(); - Mutex::Locker event_locker(m_events_mutex); - m_events.clear(); } uint32_t