124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Broadcaster.cpp -----------------------------------------*- C++ -*-===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Broadcaster.h" 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Log.h" 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Event.h" 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/StreamString.h" 1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private-log.h" 2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb; 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private; 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 245a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcaster::Broadcaster (BroadcasterManager *manager, const char *name) : 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_broadcaster_name (name), 2649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton m_listeners (), 2749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton m_listeners_mutex (Mutex::eMutexTypeRecursive), 28b0cb717846f1b732245c402864987a106dfd28acJim Ingham m_hijacking_listeners(), 295a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_hijacking_masks(), 305a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_manager (manager) 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 32952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf ("%p Broadcaster::Broadcaster(\"%s\")", this, m_broadcaster_name.AsCString()); 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::~Broadcaster() 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 40952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf ("%p Broadcaster::~Broadcaster(\"%s\")", this, m_broadcaster_name.AsCString()); 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 442f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton Clear(); 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 472f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Claytonvoid 485a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcaster::CheckInWithManager () 495a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{ 505a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham if (m_manager != NULL) 515a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham { 525a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_manager->SignUpListenersForBroadcaster(*this); 535a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham } 545a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham} 555a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 565a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamvoid 572f57db09a49f2a05a620b8163bbe1e748a46ec73Greg ClaytonBroadcaster::Clear() 582f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton{ 592f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton Mutex::Locker listeners_locker(m_listeners_mutex); 602f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton 612f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton // Make sure the listener forgets about this broadcaster. We do 622f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton // this in the broadcaster in case the broadcaster object initiates 632f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton // the removal. 642f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton 652f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton collection::iterator pos, end = m_listeners.end(); 662f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton for (pos = m_listeners.begin(); pos != end; ++pos) 672f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton pos->first->BroadcasterWillDestruct (this); 682f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton 692f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton m_listeners.clear(); 702f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton} 7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst ConstString & 7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::GetBroadcasterName () 7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_broadcaster_name; 7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Claytonbool 7849ce682dfa7993d31206cea19ce7006cd3f3077eGreg ClaytonBroadcaster::GetEventNames (Stream &s, uint32_t event_mask, bool prefix_with_broadcaster_name) const 7949ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton{ 8049ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton uint32_t num_names_added = 0; 8149ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton if (event_mask && !m_event_names.empty()) 8249ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton { 8349ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton event_names_map::const_iterator end = m_event_names.end(); 8449ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton for (uint32_t bit=1u, mask=event_mask; mask != 0 && bit != 0; bit <<= 1, mask >>= 1) 8549ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton { 8649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton if (mask & 1) 8749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton { 8849ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton event_names_map::const_iterator pos = m_event_names.find(bit); 8949ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton if (pos != end) 9049ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton { 9149ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton if (num_names_added > 0) 9249ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton s.PutCString(", "); 9349ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton 9449ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton if (prefix_with_broadcaster_name) 9549ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton { 9649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton s.PutCString (m_broadcaster_name.GetCString()); 9749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton s.PutChar('.'); 9849ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton } 9949ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton s.PutCString(pos->second.c_str()); 10049ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton ++num_names_added; 10149ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton } 10249ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton } 10349ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton } 10449ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton } 10549ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton return num_names_added > 0; 10649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton} 10749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton 10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::AddInitialEventsToListener (Listener *listener, uint32_t requested_events) 11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t 11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::AddListener (Listener* listener, uint32_t event_mask) 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 117e5001f50d6978b15e6957c1834412256054edafaJohnny Chen if (listener == NULL) 118e5001f50d6978b15e6957c1834412256054edafaJohnny Chen return 0; 119e5001f50d6978b15e6957c1834412256054edafaJohnny Chen 12049ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton Mutex::Locker locker(m_listeners_mutex); 12149ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton collection::iterator pos, end = m_listeners.end(); 12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner collection::iterator existing_pos = end; 12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // See if we already have this listener, and if so, update its mask 12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t taken_event_types = 0; 12649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton for (pos = m_listeners.begin(); pos != end; ++pos) 12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (pos->first == listener) 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner existing_pos = pos; 13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // For now don't descriminate on who gets what 13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // FIXME: Implement "unique listener for this bit" mask 13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // taken_event_types |= pos->second; 13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Each event bit in a Broadcaster object can only be used 13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // by one listener 13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t available_event_types = ~taken_event_types & event_mask; 13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (available_event_types) 14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If we didn't find our listener, add it 14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (existing_pos == end) 14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Grant a new listener the available event bits 14549ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton m_listeners.push_back(std::make_pair(listener, available_event_types)); 14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Grant the existing listener the available event bits 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner existing_pos->second |= available_event_types; 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Individual broadcasters decide whether they have outstanding data when a 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // listener attaches, and insert it into the listener with this method. 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner AddInitialEventsToListener (listener, available_event_types); 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Return the event bits that were granted to the listener 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return available_event_types; 16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::EventTypeHasListeners (uint32_t event_type) 16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 16649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton Mutex::Locker locker (m_listeners_mutex); 16763e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham 168b0cb717846f1b732245c402864987a106dfd28acJim Ingham if (m_hijacking_listeners.size() > 0 && event_type & m_hijacking_masks.back()) 16963e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham return true; 17063e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham 17149ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton if (m_listeners.empty()) 17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 17449ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton collection::iterator pos, end = m_listeners.end(); 17549ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton for (pos = m_listeners.begin(); pos != end; ++pos) 17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (pos->second & event_type) 17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::RemoveListener (Listener* listener, uint32_t event_mask) 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 18649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton Mutex::Locker locker(m_listeners_mutex); 18749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton collection::iterator pos, end = m_listeners.end(); 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // See if we already have this listener, and if so, update its mask 18949ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton for (pos = m_listeners.begin(); pos != end; ++pos) 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (pos->first == listener) 19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Relinquish all event bits in "event_mask" 19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner pos->second &= ~event_mask; 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If all bits have been relinquished then remove this listener 19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (pos->second == 0) 19749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton m_listeners.erase (pos); 19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::BroadcastEvent (EventSP &event_sp) 20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return PrivateBroadcastEvent (event_sp, false); 20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::BroadcastEventIfUnique (EventSP &event_sp) 21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return PrivateBroadcastEvent (event_sp, true); 21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::PrivateBroadcastEvent (EventSP &event_sp, bool unique) 21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Can't add a NULL event... 22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_sp.get() == NULL) 22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Update the broadcaster on this event 22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner event_sp->SetBroadcaster (this); 22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t event_type = event_sp->GetType(); 22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2286ae318c875fac58fb2d952739ee554c5ba18368fJim Ingham Mutex::Locker event_types_locker(m_listeners_mutex); 229a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton 230a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton Listener *hijacking_listener = NULL; 231a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton if (!m_hijacking_listeners.empty()) 232a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton { 233a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton assert (!m_hijacking_masks.empty()); 234a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton hijacking_listener = m_hijacking_listeners.back(); 235a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton if ((event_type & m_hijacking_masks.back()) == 0) 236a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton hijacking_listener = NULL; 237a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton } 238a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton 239952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS)); 24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StreamString event_description; 24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner event_sp->Dump (&event_description); 2446ae318c875fac58fb2d952739ee554c5ba18368fJim Ingham log->Printf ("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, unique =%i) hijack = %p", 24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner this, 24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_broadcaster_name.AsCString(""), 24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner event_description.GetData(), 2486ae318c875fac58fb2d952739ee554c5ba18368fJim Ingham unique, 249a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton hijacking_listener); 25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 252a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton if (hijacking_listener) 25363e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham { 254b0cb717846f1b732245c402864987a106dfd28acJim Ingham if (unique && hijacking_listener->PeekAtNextEventForBroadcasterWithType (this, event_type)) 25563e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham return; 256b0cb717846f1b732245c402864987a106dfd28acJim Ingham hijacking_listener->AddEvent (event_sp); 25763e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham } 25863e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham else 25963e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham { 26049ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton collection::iterator pos, end = m_listeners.end(); 26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26363e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham // Iterate through all listener/mask pairs 26449ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton for (pos = m_listeners.begin(); pos != end; ++pos) 26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 26663e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham // If the listener's mask matches any bits that we just set, then 26763e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham // put the new event on its event queue. 26863e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham if (event_type & pos->second) 26963e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham { 27063e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham if (unique && pos->first->PeekAtNextEventForBroadcasterWithType (this, event_type)) 27163e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham continue; 27263e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham pos->first->AddEvent (event_sp); 27363e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham } 27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::BroadcastEvent (uint32_t event_type, EventData *event_data) 28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner EventSP event_sp (new Event (event_type, event_data)); 28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner PrivateBroadcastEvent (event_sp, false); 28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::BroadcastEventIfUnique (uint32_t event_type, EventData *event_data) 28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner EventSP event_sp (new Event (event_type, event_data)); 28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner PrivateBroadcastEvent (event_sp, true); 29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29263e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Inghambool 29363e24d7aeae8a7feb2aae0581e597b922749d4a1Jim InghamBroadcaster::HijackBroadcaster (Listener *listener, uint32_t event_mask) 29463e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham{ 29549ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton Mutex::Locker event_types_locker(m_listeners_mutex); 2966ae318c875fac58fb2d952739ee554c5ba18368fJim Ingham 297952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS)); 298b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen if (log) 299b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen { 300b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen log->Printf ("%p Broadcaster(\"%s\")::HijackBroadcaster (listener(\"%s\")=%p)", 301b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen this, 302b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen m_broadcaster_name.AsCString(""), 303b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen listener->m_name.c_str(), 304b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen listener); 305b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen } 306b0cb717846f1b732245c402864987a106dfd28acJim Ingham m_hijacking_listeners.push_back(listener); 307b0cb717846f1b732245c402864987a106dfd28acJim Ingham m_hijacking_masks.push_back(event_mask); 30863e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham return true; 30963e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham} 31063e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham 31163e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Inghamvoid 31263e24d7aeae8a7feb2aae0581e597b922749d4a1Jim InghamBroadcaster::RestoreBroadcaster () 31363e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham{ 31449ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton Mutex::Locker event_types_locker(m_listeners_mutex); 315b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen 316952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS)); 317b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen if (log) 318b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen { 319b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen Listener *listener = m_hijacking_listeners.back(); 320b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen log->Printf ("%p Broadcaster(\"%s\")::RestoreBroadcaster (about to pop listener(\"%s\")=%p)", 321b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen this, 322b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen m_broadcaster_name.AsCString(""), 323b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen listener->m_name.c_str(), 324b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen listener); 325b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen } 326b0cb717846f1b732245c402864987a106dfd28acJim Ingham m_hijacking_listeners.pop_back(); 327b0cb717846f1b732245c402864987a106dfd28acJim Ingham m_hijacking_masks.pop_back(); 32863e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham} 32963e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham 3305a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamConstString & 3315a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcaster::GetBroadcasterClass() const 3325a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{ 3335a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham static ConstString class_name ("lldb.anonymous"); 3345a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham return class_name; 3355a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham} 3365a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 3375a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcastEventSpec::BroadcastEventSpec (const BroadcastEventSpec &rhs) : 3385a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_broadcaster_class (rhs.m_broadcaster_class), 3395a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_event_bits (rhs.m_event_bits) 3405a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{ 3415a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham} 3425a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 3435a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghambool 3445a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcastEventSpec::operator< (const BroadcastEventSpec &rhs) const 3455a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{ 3465a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham if (GetBroadcasterClass() == rhs.GetBroadcasterClass()) 3475a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham { 3485a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham return GetEventBits() < rhs.GetEventBits(); 3495a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham } 3505a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham else 3515a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham { 3525a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham return GetBroadcasterClass() < rhs.GetBroadcasterClass(); 3535a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham } 3545a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham} 3555a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 3565a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamconst BroadcastEventSpec & 3575a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcastEventSpec::operator= (const BroadcastEventSpec &rhs) 3585a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{ 3595a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_broadcaster_class = rhs.m_broadcaster_class; 3605a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_event_bits = rhs.m_event_bits; 3615a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham return *this; 3625a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham} 3635a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 3645a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::BroadcasterManager() : 3655a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_manager_mutex(Mutex::eMutexTypeRecursive) 3665a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{ 3675a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 3685a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham} 3695a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 3705a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamuint32_t 3715a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::RegisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec) 3725a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{ 3735a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham Mutex::Locker locker(m_manager_mutex); 3745a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 3755a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham collection::iterator iter = m_event_map.begin(), end_iter = m_event_map.end(); 3765a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham uint32_t available_bits = event_spec.GetEventBits(); 3775a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 3785a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham while (iter != end_iter 3795a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham && (iter = find_if (iter, end_iter, BroadcasterClassMatches(event_spec.GetBroadcasterClass()))) != end_iter) 3805a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham { 3815a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham available_bits &= ~((*iter).first.GetEventBits()); 3825a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham iter++; 3835a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham } 3845a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 3855a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham if (available_bits != 0) 3865a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham { 3875a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_event_map.insert (event_listener_key (BroadcastEventSpec (event_spec.GetBroadcasterClass(), available_bits), &listener)); 3885a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_listeners.insert(&listener); 3895a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham } 3905a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 3915a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham return available_bits; 3925a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham} 3935a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 3945a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghambool 3955a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::UnregisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec) 3965a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{ 3975a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham Mutex::Locker locker(m_manager_mutex); 3985a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham bool removed_some = false; 3995a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4005a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham if (m_listeners.erase(&listener) == 0) 4015a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham return false; 4025a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4035a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham ListenerMatchesAndSharedBits predicate (event_spec, listener); 4045a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham std::vector<BroadcastEventSpec> to_be_readded; 4055a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham uint32_t event_bits_to_remove = event_spec.GetEventBits(); 4065a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4075a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham // Go through the map and delete the exact matches, and build a list of matches that weren't exact to re-add: 4085a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham while (1) 4095a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham { 4105a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham collection::iterator iter, end_iter = m_event_map.end(); 4115a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham iter = find_if (m_event_map.begin(), end_iter, predicate); 4125a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham if (iter == end_iter) 4135a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham { 4145a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham break; 4155a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham } 4165a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham else 4175a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham { 4185a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham uint32_t iter_event_bits = (*iter).first.GetEventBits(); 4195a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham removed_some = true; 4205a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4215a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham if (event_bits_to_remove != iter_event_bits) 4225a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham { 4235a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham uint32_t new_event_bits = iter_event_bits & ~event_bits_to_remove; 4245a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham to_be_readded.push_back(BroadcastEventSpec (event_spec.GetBroadcasterClass(), new_event_bits)); 4255a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham } 4265a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_event_map.erase (iter); 4275a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham } 4285a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham } 4295a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4305a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham // Okay now add back the bits that weren't completely removed: 4315a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham for (size_t i = 0; i < to_be_readded.size(); i++) 4325a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham { 4335a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_event_map.insert (event_listener_key (to_be_readded[i], &listener)); 4345a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham } 4355a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4365a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham return removed_some; 4375a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham} 4385a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4395a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamListener * 4405a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::GetListenerForEventSpec (BroadcastEventSpec event_spec) const 4415a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{ 4425a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham Mutex::Locker locker(*(const_cast<Mutex *> (&m_manager_mutex))); 4435a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4445a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham collection::const_iterator iter, end_iter = m_event_map.end(); 4455a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham iter = find_if (m_event_map.begin(), end_iter, BroadcastEventSpecMatches (event_spec)); 4465a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham if (iter != end_iter) 4475a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham return (*iter).second; 4485a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham else 4495a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham return NULL; 4505a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham} 4515a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4525a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamvoid 4535a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::RemoveListener (Listener &listener) 4545a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{ 4555a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham Mutex::Locker locker(m_manager_mutex); 4565a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham ListenerMatches predicate (listener); 4575a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4585a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4595a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham if (m_listeners.erase (&listener) == 0) 4605a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham return; 4615a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4625a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham while (1) 4635a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham { 4645a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham collection::iterator iter, end_iter = m_event_map.end(); 4655a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham iter = find_if (m_event_map.begin(), end_iter, predicate); 4665a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham if (iter == end_iter) 4675a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham break; 4685a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham else 4695a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_event_map.erase(iter); 4705a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham } 4715a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham} 4725a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4735a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamvoid 4745a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::SignUpListenersForBroadcaster (Broadcaster &broadcaster) 4755a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{ 4765a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham Mutex::Locker locker(m_manager_mutex); 4775a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4785a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham collection::iterator iter = m_event_map.begin(), end_iter = m_event_map.end(); 4795a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4805a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham while (iter != end_iter 4815a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham && (iter = find_if (iter, end_iter, BroadcasterClassMatches(broadcaster.GetBroadcasterClass()))) != end_iter) 4825a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham { 4835a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham (*iter).second->StartListeningForEvents (&broadcaster, (*iter).first.GetEventBits()); 4845a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham iter++; 4855a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham } 4865a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham} 4875a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4885a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamvoid 4895a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::Clear () 4905a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{ 4915a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham Mutex::Locker locker(m_manager_mutex); 4925a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham listener_collection::iterator end_iter = m_listeners.end(); 4935a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4945a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham for (listener_collection::iterator iter = m_listeners.begin(); iter != end_iter; iter++) 4955a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham (*iter)->BroadcasterManagerWillDestruct(this); 4965a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_listeners.clear(); 4975a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham m_event_map.clear(); 4985a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4995a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham} 500