1254721Semaste//===-- Listener.cpp --------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Core/Listener.h" 11254721Semaste 12254721Semaste// C Includes 13254721Semaste// C++ Includes 14254721Semaste// Other libraries and framework includes 15254721Semaste// Project includes 16254721Semaste#include "lldb/Core/Broadcaster.h" 17254721Semaste#include "lldb/Core/Log.h" 18254721Semaste#include "lldb/Core/StreamString.h" 19254721Semaste#include "lldb/Core/Event.h" 20254721Semaste#include "lldb/Host/TimeValue.h" 21254721Semaste#include "lldb/lldb-private-log.h" 22254721Semaste#include <algorithm> 23254721Semaste 24254721Semasteusing namespace lldb; 25254721Semasteusing namespace lldb_private; 26254721Semaste 27254721SemasteListener::Listener(const char *name) : 28254721Semaste m_name (name), 29254721Semaste m_broadcasters(), 30254721Semaste m_broadcasters_mutex (Mutex::eMutexTypeRecursive), 31254721Semaste m_events (), 32254721Semaste m_events_mutex (Mutex::eMutexTypeRecursive), 33254721Semaste m_cond_wait() 34254721Semaste{ 35254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 36254721Semaste if (log) 37254721Semaste log->Printf ("%p Listener::Listener('%s')", this, m_name.c_str()); 38254721Semaste} 39254721Semaste 40254721SemasteListener::~Listener() 41254721Semaste{ 42254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 43254721Semaste Mutex::Locker locker (m_broadcasters_mutex); 44254721Semaste 45254721Semaste size_t num_managers = m_broadcaster_managers.size(); 46254721Semaste 47254721Semaste for (size_t i = 0; i < num_managers; i++) 48254721Semaste m_broadcaster_managers[i]->RemoveListener(*this); 49254721Semaste 50254721Semaste if (log) 51254721Semaste log->Printf ("%p Listener::~Listener('%s')", this, m_name.c_str()); 52254721Semaste Clear(); 53254721Semaste} 54254721Semaste 55254721Semastevoid 56254721SemasteListener::Clear() 57254721Semaste{ 58254721Semaste Mutex::Locker locker(m_broadcasters_mutex); 59254721Semaste broadcaster_collection::iterator pos, end = m_broadcasters.end(); 60254721Semaste for (pos = m_broadcasters.begin(); pos != end; ++pos) 61254721Semaste pos->first->RemoveListener (this, pos->second.event_mask); 62254721Semaste m_broadcasters.clear(); 63254721Semaste m_cond_wait.SetValue (false, eBroadcastNever); 64254721Semaste m_broadcasters.clear(); 65254721Semaste Mutex::Locker event_locker(m_events_mutex); 66254721Semaste m_events.clear(); 67254721Semaste} 68254721Semaste 69254721Semasteuint32_t 70254721SemasteListener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask) 71254721Semaste{ 72254721Semaste if (broadcaster) 73254721Semaste { 74254721Semaste // Scope for "locker" 75254721Semaste // Tell the broadcaster to add this object as a listener 76254721Semaste { 77254721Semaste Mutex::Locker locker(m_broadcasters_mutex); 78254721Semaste m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask))); 79254721Semaste } 80254721Semaste 81254721Semaste uint32_t acquired_mask = broadcaster->AddListener (this, event_mask); 82254721Semaste 83254721Semaste if (event_mask != acquired_mask) 84254721Semaste { 85254721Semaste 86254721Semaste } 87254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS)); 88254721Semaste if (log) 89254721Semaste log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s", 90254721Semaste this, 91254721Semaste broadcaster, 92254721Semaste event_mask, 93254721Semaste acquired_mask, 94254721Semaste m_name.c_str()); 95254721Semaste 96254721Semaste return acquired_mask; 97254721Semaste 98254721Semaste } 99254721Semaste return 0; 100254721Semaste} 101254721Semaste 102254721Semasteuint32_t 103254721SemasteListener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask, HandleBroadcastCallback callback, void *callback_user_data) 104254721Semaste{ 105254721Semaste if (broadcaster) 106254721Semaste { 107254721Semaste // Scope for "locker" 108254721Semaste // Tell the broadcaster to add this object as a listener 109254721Semaste { 110254721Semaste Mutex::Locker locker(m_broadcasters_mutex); 111254721Semaste m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask, callback, callback_user_data))); 112254721Semaste } 113254721Semaste 114254721Semaste uint32_t acquired_mask = broadcaster->AddListener (this, event_mask); 115254721Semaste 116254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS)); 117254721Semaste if (log) 118254721Semaste log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x, callback = %p, user_data = %p) acquired_mask = 0x%8.8x for %s", 119254721Semaste this, broadcaster, event_mask, callback, callback_user_data, acquired_mask, m_name.c_str()); 120254721Semaste 121254721Semaste return acquired_mask; 122254721Semaste } 123254721Semaste return 0; 124254721Semaste} 125254721Semaste 126254721Semastebool 127254721SemasteListener::StopListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask) 128254721Semaste{ 129254721Semaste if (broadcaster) 130254721Semaste { 131254721Semaste // Scope for "locker" 132254721Semaste { 133254721Semaste Mutex::Locker locker(m_broadcasters_mutex); 134254721Semaste m_broadcasters.erase (broadcaster); 135254721Semaste } 136254721Semaste // Remove the broadcaster from our set of broadcasters 137254721Semaste return broadcaster->RemoveListener (this, event_mask); 138254721Semaste } 139254721Semaste 140254721Semaste return false; 141254721Semaste} 142254721Semaste 143254721Semaste// Called when a Broadcaster is in its destuctor. We need to remove all 144254721Semaste// knowledge of this broadcaster and any events that it may have queued up 145254721Semastevoid 146254721SemasteListener::BroadcasterWillDestruct (Broadcaster *broadcaster) 147254721Semaste{ 148254721Semaste // Scope for "broadcasters_locker" 149254721Semaste { 150254721Semaste Mutex::Locker broadcasters_locker(m_broadcasters_mutex); 151254721Semaste m_broadcasters.erase (broadcaster); 152254721Semaste } 153254721Semaste 154254721Semaste // Scope for "event_locker" 155254721Semaste { 156254721Semaste Mutex::Locker event_locker(m_events_mutex); 157254721Semaste // Remove all events for this broadcaster object. 158254721Semaste event_collection::iterator pos = m_events.begin(); 159254721Semaste while (pos != m_events.end()) 160254721Semaste { 161254721Semaste if ((*pos)->GetBroadcaster() == broadcaster) 162254721Semaste pos = m_events.erase(pos); 163254721Semaste else 164254721Semaste ++pos; 165254721Semaste } 166254721Semaste 167254721Semaste if (m_events.empty()) 168254721Semaste m_cond_wait.SetValue (false, eBroadcastNever); 169254721Semaste 170254721Semaste } 171254721Semaste} 172254721Semaste 173254721Semastevoid 174254721SemasteListener::BroadcasterManagerWillDestruct (BroadcasterManager *manager) 175254721Semaste{ 176254721Semaste // Just need to remove this broadcast manager from the list of managers: 177254721Semaste broadcaster_manager_collection::iterator iter, end_iter = m_broadcaster_managers.end(); 178254721Semaste iter = find(m_broadcaster_managers.begin(), end_iter, manager); 179254721Semaste if (iter != end_iter) 180254721Semaste m_broadcaster_managers.erase (iter); 181254721Semaste} 182254721Semaste 183254721Semastevoid 184254721SemasteListener::AddEvent (EventSP &event_sp) 185254721Semaste{ 186254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS)); 187254721Semaste if (log) 188254721Semaste log->Printf ("%p Listener('%s')::AddEvent (event_sp = {%p})", this, m_name.c_str(), event_sp.get()); 189254721Semaste 190254721Semaste // Scope for "locker" 191254721Semaste { 192254721Semaste Mutex::Locker locker(m_events_mutex); 193254721Semaste m_events.push_back (event_sp); 194254721Semaste } 195254721Semaste m_cond_wait.SetValue (true, eBroadcastAlways); 196254721Semaste} 197254721Semaste 198254721Semasteclass EventBroadcasterMatches 199254721Semaste{ 200254721Semastepublic: 201254721Semaste EventBroadcasterMatches (Broadcaster *broadcaster) : 202254721Semaste m_broadcaster (broadcaster) { 203254721Semaste } 204254721Semaste 205254721Semaste bool operator() (const EventSP &event_sp) const 206254721Semaste { 207254721Semaste if (event_sp->BroadcasterIs(m_broadcaster)) 208254721Semaste return true; 209254721Semaste else 210254721Semaste return false; 211254721Semaste } 212254721Semaste 213254721Semasteprivate: 214254721Semaste Broadcaster *m_broadcaster; 215254721Semaste 216254721Semaste}; 217254721Semaste 218254721Semasteclass EventMatcher 219254721Semaste{ 220254721Semastepublic: 221254721Semaste EventMatcher (Broadcaster *broadcaster, const ConstString *broadcaster_names, uint32_t num_broadcaster_names, uint32_t event_type_mask) : 222254721Semaste m_broadcaster (broadcaster), 223254721Semaste m_broadcaster_names (broadcaster_names), 224254721Semaste m_num_broadcaster_names (num_broadcaster_names), 225254721Semaste m_event_type_mask (event_type_mask) 226254721Semaste { 227254721Semaste } 228254721Semaste 229254721Semaste bool operator() (const EventSP &event_sp) const 230254721Semaste { 231254721Semaste if (m_broadcaster && !event_sp->BroadcasterIs(m_broadcaster)) 232254721Semaste return false; 233254721Semaste 234254721Semaste if (m_broadcaster_names) 235254721Semaste { 236254721Semaste bool found_source = false; 237254721Semaste const ConstString &event_broadcaster_name = event_sp->GetBroadcaster()->GetBroadcasterName(); 238254721Semaste for (uint32_t i=0; i<m_num_broadcaster_names; ++i) 239254721Semaste { 240254721Semaste if (m_broadcaster_names[i] == event_broadcaster_name) 241254721Semaste { 242254721Semaste found_source = true; 243254721Semaste break; 244254721Semaste } 245254721Semaste } 246254721Semaste if (!found_source) 247254721Semaste return false; 248254721Semaste } 249254721Semaste 250254721Semaste if (m_event_type_mask == 0 || m_event_type_mask & event_sp->GetType()) 251254721Semaste return true; 252254721Semaste return false; 253254721Semaste } 254254721Semaste 255254721Semasteprivate: 256254721Semaste Broadcaster *m_broadcaster; 257254721Semaste const ConstString *m_broadcaster_names; 258254721Semaste const uint32_t m_num_broadcaster_names; 259254721Semaste const uint32_t m_event_type_mask; 260254721Semaste}; 261254721Semaste 262254721Semaste 263254721Semastebool 264254721SemasteListener::FindNextEventInternal 265254721Semaste( 266254721Semaste Broadcaster *broadcaster, // NULL for any broadcaster 267254721Semaste const ConstString *broadcaster_names, // NULL for any event 268254721Semaste uint32_t num_broadcaster_names, 269254721Semaste uint32_t event_type_mask, 270254721Semaste EventSP &event_sp, 271254721Semaste bool remove) 272254721Semaste{ 273254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS)); 274254721Semaste 275254721Semaste Mutex::Locker lock(m_events_mutex); 276254721Semaste 277254721Semaste if (m_events.empty()) 278254721Semaste return false; 279254721Semaste 280254721Semaste 281254721Semaste Listener::event_collection::iterator pos = m_events.end(); 282254721Semaste 283254721Semaste if (broadcaster == NULL && broadcaster_names == NULL && event_type_mask == 0) 284254721Semaste { 285254721Semaste pos = m_events.begin(); 286254721Semaste } 287254721Semaste else 288254721Semaste { 289254721Semaste pos = std::find_if (m_events.begin(), m_events.end(), EventMatcher (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask)); 290254721Semaste } 291254721Semaste 292254721Semaste if (pos != m_events.end()) 293254721Semaste { 294254721Semaste event_sp = *pos; 295254721Semaste 296254721Semaste if (log) 297254721Semaste log->Printf ("%p '%s' Listener::FindNextEventInternal(broadcaster=%p, broadcaster_names=%p[%u], event_type_mask=0x%8.8x, remove=%i) event %p", 298254721Semaste this, 299254721Semaste GetName(), 300254721Semaste broadcaster, 301254721Semaste broadcaster_names, 302254721Semaste num_broadcaster_names, 303254721Semaste event_type_mask, 304254721Semaste remove, 305254721Semaste event_sp.get()); 306254721Semaste 307254721Semaste if (remove) 308254721Semaste { 309254721Semaste m_events.erase(pos); 310254721Semaste 311254721Semaste if (m_events.empty()) 312254721Semaste m_cond_wait.SetValue (false, eBroadcastNever); 313254721Semaste } 314254721Semaste 315254721Semaste // Unlock the event queue here. We've removed this event and are about to return 316254721Semaste // it so it should be okay to get the next event off the queue here - and it might 317254721Semaste // be useful to do that in the "DoOnRemoval". 318254721Semaste lock.Unlock(); 319254721Semaste 320254721Semaste // Don't call DoOnRemoval if you aren't removing the event... 321254721Semaste if (remove) 322254721Semaste event_sp->DoOnRemoval(); 323254721Semaste 324254721Semaste return true; 325254721Semaste } 326254721Semaste 327254721Semaste event_sp.reset(); 328254721Semaste return false; 329254721Semaste} 330254721Semaste 331254721SemasteEvent * 332254721SemasteListener::PeekAtNextEvent () 333254721Semaste{ 334254721Semaste EventSP event_sp; 335254721Semaste if (FindNextEventInternal (NULL, NULL, 0, 0, event_sp, false)) 336254721Semaste return event_sp.get(); 337254721Semaste return NULL; 338254721Semaste} 339254721Semaste 340254721SemasteEvent * 341254721SemasteListener::PeekAtNextEventForBroadcaster (Broadcaster *broadcaster) 342254721Semaste{ 343254721Semaste EventSP event_sp; 344254721Semaste if (FindNextEventInternal (broadcaster, NULL, 0, 0, event_sp, false)) 345254721Semaste return event_sp.get(); 346254721Semaste return NULL; 347254721Semaste} 348254721Semaste 349254721SemasteEvent * 350254721SemasteListener::PeekAtNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask) 351254721Semaste{ 352254721Semaste EventSP event_sp; 353254721Semaste if (FindNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp, false)) 354254721Semaste return event_sp.get(); 355254721Semaste return NULL; 356254721Semaste} 357254721Semaste 358254721Semaste 359254721Semastebool 360254721SemasteListener::GetNextEventInternal 361254721Semaste( 362254721Semaste Broadcaster *broadcaster, // NULL for any broadcaster 363254721Semaste const ConstString *broadcaster_names, // NULL for any event 364254721Semaste uint32_t num_broadcaster_names, 365254721Semaste uint32_t event_type_mask, 366254721Semaste EventSP &event_sp 367254721Semaste) 368254721Semaste{ 369254721Semaste return FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true); 370254721Semaste} 371254721Semaste 372254721Semastebool 373254721SemasteListener::GetNextEvent (EventSP &event_sp) 374254721Semaste{ 375254721Semaste return GetNextEventInternal (NULL, NULL, 0, 0, event_sp); 376254721Semaste} 377254721Semaste 378254721Semaste 379254721Semastebool 380254721SemasteListener::GetNextEventForBroadcaster (Broadcaster *broadcaster, EventSP &event_sp) 381254721Semaste{ 382254721Semaste return GetNextEventInternal (broadcaster, NULL, 0, 0, event_sp); 383254721Semaste} 384254721Semaste 385254721Semastebool 386254721SemasteListener::GetNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask, EventSP &event_sp) 387254721Semaste{ 388254721Semaste return GetNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp); 389254721Semaste} 390254721Semaste 391254721Semaste 392254721Semastebool 393254721SemasteListener::WaitForEventsInternal 394254721Semaste( 395254721Semaste const TimeValue *timeout, 396254721Semaste Broadcaster *broadcaster, // NULL for any broadcaster 397254721Semaste const ConstString *broadcaster_names, // NULL for any event 398254721Semaste uint32_t num_broadcaster_names, 399254721Semaste uint32_t event_type_mask, 400254721Semaste EventSP &event_sp 401254721Semaste) 402254721Semaste{ 403254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS)); 404254721Semaste bool timed_out = false; 405254721Semaste 406254721Semaste if (log) 407254721Semaste { 408254721Semaste log->Printf ("%p Listener::WaitForEventsInternal (timeout = { %p }) for %s", 409254721Semaste this, timeout, m_name.c_str()); 410254721Semaste } 411254721Semaste 412254721Semaste while (1) 413254721Semaste { 414254721Semaste // Note, we don't want to lock the m_events_mutex in the call to GetNextEventInternal, since the DoOnRemoval 415254721Semaste // code might require that new events be serviced. For instance, the Breakpoint Command's 416254721Semaste if (GetNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp)) 417254721Semaste return true; 418254721Semaste 419254721Semaste { 420254721Semaste // Reset condition value to false, so we can wait for new events to be 421254721Semaste // added that might meet our current filter 422254721Semaste // But first poll for any new event that might satisfy our condition, and if so consume it, 423254721Semaste // otherwise wait. 424254721Semaste 425254721Semaste Mutex::Locker event_locker(m_events_mutex); 426254721Semaste const bool remove = false; 427254721Semaste if (FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, remove)) 428254721Semaste continue; 429254721Semaste else 430254721Semaste m_cond_wait.SetValue (false, eBroadcastNever); 431254721Semaste } 432254721Semaste 433254721Semaste if (m_cond_wait.WaitForValueEqualTo (true, timeout, &timed_out)) 434254721Semaste continue; 435254721Semaste 436254721Semaste else if (timed_out) 437254721Semaste { 438254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS); 439254721Semaste if (log) 440254721Semaste log->Printf ("%p Listener::WaitForEventsInternal() timed out for %s", this, m_name.c_str()); 441254721Semaste break; 442254721Semaste } 443254721Semaste else 444254721Semaste { 445254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS); 446254721Semaste if (log) 447254721Semaste log->Printf ("%p Listener::WaitForEventsInternal() unknown error for %s", this, m_name.c_str()); 448254721Semaste break; 449254721Semaste } 450254721Semaste } 451254721Semaste 452254721Semaste return false; 453254721Semaste} 454254721Semaste 455254721Semastebool 456254721SemasteListener::WaitForEventForBroadcasterWithType 457254721Semaste( 458254721Semaste const TimeValue *timeout, 459254721Semaste Broadcaster *broadcaster, 460254721Semaste uint32_t event_type_mask, 461254721Semaste EventSP &event_sp 462254721Semaste) 463254721Semaste{ 464254721Semaste return WaitForEventsInternal (timeout, broadcaster, NULL, 0, event_type_mask, event_sp); 465254721Semaste} 466254721Semaste 467254721Semastebool 468254721SemasteListener::WaitForEventForBroadcaster 469254721Semaste( 470254721Semaste const TimeValue *timeout, 471254721Semaste Broadcaster *broadcaster, 472254721Semaste EventSP &event_sp 473254721Semaste) 474254721Semaste{ 475254721Semaste return WaitForEventsInternal (timeout, broadcaster, NULL, 0, 0, event_sp); 476254721Semaste} 477254721Semaste 478254721Semastebool 479254721SemasteListener::WaitForEvent (const TimeValue *timeout, EventSP &event_sp) 480254721Semaste{ 481254721Semaste return WaitForEventsInternal (timeout, NULL, NULL, 0, 0, event_sp); 482254721Semaste} 483254721Semaste 484254721Semaste//Listener::broadcaster_collection::iterator 485254721Semaste//Listener::FindBroadcasterWithMask (Broadcaster *broadcaster, uint32_t event_mask, bool exact) 486254721Semaste//{ 487254721Semaste// broadcaster_collection::iterator pos; 488254721Semaste// broadcaster_collection::iterator end = m_broadcasters.end(); 489254721Semaste// for (pos = m_broadcasters.find (broadcaster); 490254721Semaste// pos != end && pos->first == broadcaster; 491254721Semaste// ++pos) 492254721Semaste// { 493254721Semaste// if (exact) 494254721Semaste// { 495254721Semaste// if ((event_mask & pos->second.event_mask) == event_mask) 496254721Semaste// return pos; 497254721Semaste// } 498254721Semaste// else 499254721Semaste// { 500254721Semaste// if (event_mask & pos->second.event_mask) 501254721Semaste// return pos; 502254721Semaste// } 503254721Semaste// } 504254721Semaste// return end; 505254721Semaste//} 506254721Semaste 507254721Semastesize_t 508254721SemasteListener::HandleBroadcastEvent (EventSP &event_sp) 509254721Semaste{ 510254721Semaste size_t num_handled = 0; 511254721Semaste Mutex::Locker locker(m_broadcasters_mutex); 512254721Semaste Broadcaster *broadcaster = event_sp->GetBroadcaster(); 513254721Semaste broadcaster_collection::iterator pos; 514254721Semaste broadcaster_collection::iterator end = m_broadcasters.end(); 515254721Semaste for (pos = m_broadcasters.find (broadcaster); 516254721Semaste pos != end && pos->first == broadcaster; 517254721Semaste ++pos) 518254721Semaste { 519254721Semaste BroadcasterInfo info = pos->second; 520254721Semaste if (event_sp->GetType () & info.event_mask) 521254721Semaste { 522254721Semaste if (info.callback != NULL) 523254721Semaste { 524254721Semaste info.callback (event_sp, info.callback_user_data); 525254721Semaste ++num_handled; 526254721Semaste } 527254721Semaste } 528254721Semaste } 529254721Semaste return num_handled; 530254721Semaste} 531254721Semaste 532254721Semasteuint32_t 533254721SemasteListener::StartListeningForEventSpec (BroadcasterManager &manager, 534254721Semaste const BroadcastEventSpec &event_spec) 535254721Semaste{ 536254721Semaste // The BroadcasterManager mutex must be locked before m_broadcasters_mutex 537254721Semaste // to avoid violating the lock hierarchy (manager before broadcasters). 538254721Semaste Mutex::Locker manager_locker(manager.m_manager_mutex); 539254721Semaste Mutex::Locker locker(m_broadcasters_mutex); 540254721Semaste 541254721Semaste uint32_t bits_acquired = manager.RegisterListenerForEvents(*this, event_spec); 542254721Semaste if (bits_acquired) 543254721Semaste m_broadcaster_managers.push_back(&manager); 544254721Semaste 545254721Semaste return bits_acquired; 546254721Semaste} 547254721Semaste 548254721Semastebool 549254721SemasteListener::StopListeningForEventSpec (BroadcasterManager &manager, 550254721Semaste const BroadcastEventSpec &event_spec) 551254721Semaste{ 552254721Semaste Mutex::Locker locker(m_broadcasters_mutex); 553254721Semaste return manager.UnregisterListenerForEvents (*this, event_spec); 554254721Semaste 555254721Semaste} 556254721Semaste 557254721Semaste 558