1343181Sdim//===-- Broadcaster.h -------------------------------------------*- C++ -*-===// 2343181Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6343181Sdim// 7343181Sdim//===----------------------------------------------------------------------===// 8343181Sdim 9343181Sdim#ifndef LLDB_UTILITY_BROADCASTER_H 10343181Sdim#define LLDB_UTILITY_BROADCASTER_H 11343181Sdim 12343181Sdim#include "lldb/Utility/ConstString.h" 13343181Sdim#include "lldb/lldb-defines.h" 14343181Sdim#include "lldb/lldb-forward.h" 15343181Sdim 16343181Sdim#include "llvm/ADT/SmallVector.h" 17343181Sdim 18343181Sdim#include <cstdint> 19343181Sdim#include <map> 20343181Sdim#include <memory> 21343181Sdim#include <mutex> 22343181Sdim#include <set> 23343181Sdim#include <string> 24343181Sdim#include <utility> 25343181Sdim#include <vector> 26343181Sdim 27343181Sdimnamespace lldb_private { 28343181Sdimclass Broadcaster; 29343181Sdimclass EventData; 30343181Sdimclass Listener; 31343181Sdimclass Stream; 32353358Sdim} // namespace lldb_private 33343181Sdim 34343181Sdimnamespace lldb_private { 35343181Sdim 36353358Sdim/// lldb::BroadcastEventSpec 37353358Sdim/// 38353358Sdim/// This class is used to specify a kind of event to register for. The 39353358Sdim/// Debugger maintains a list of BroadcastEventSpec's and when it is made 40343181Sdimclass BroadcastEventSpec { 41343181Sdimpublic: 42353358Sdim BroadcastEventSpec(ConstString broadcaster_class, uint32_t event_bits) 43343181Sdim : m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {} 44343181Sdim 45343181Sdim ~BroadcastEventSpec() = default; 46343181Sdim 47353358Sdim ConstString GetBroadcasterClass() const { return m_broadcaster_class; } 48343181Sdim 49343181Sdim uint32_t GetEventBits() const { return m_event_bits; } 50343181Sdim 51353358Sdim /// Tell whether this BroadcastEventSpec is contained in in_spec. That is: 52353358Sdim /// (a) the two spec's share the same broadcaster class (b) the event bits of 53353358Sdim /// this spec are wholly contained in those of in_spec. 54353358Sdim bool IsContainedIn(const BroadcastEventSpec &in_spec) const { 55343181Sdim if (m_broadcaster_class != in_spec.GetBroadcasterClass()) 56343181Sdim return false; 57343181Sdim uint32_t in_bits = in_spec.GetEventBits(); 58343181Sdim if (in_bits == m_event_bits) 59343181Sdim return true; 60353358Sdim 61353358Sdim if ((m_event_bits & in_bits) != 0 && (m_event_bits & ~in_bits) == 0) 62353358Sdim return true; 63353358Sdim 64343181Sdim return false; 65343181Sdim } 66343181Sdim 67343181Sdim bool operator<(const BroadcastEventSpec &rhs) const; 68343181Sdim 69343181Sdimprivate: 70343181Sdim ConstString m_broadcaster_class; 71343181Sdim uint32_t m_event_bits; 72343181Sdim}; 73343181Sdim 74343181Sdimclass BroadcasterManager 75343181Sdim : public std::enable_shared_from_this<BroadcasterManager> { 76343181Sdimpublic: 77343181Sdim friend class Listener; 78343181Sdim 79343181Sdimprotected: 80343181Sdim BroadcasterManager(); 81343181Sdim 82343181Sdimpublic: 83353358Sdim /// Listeners hold onto weak pointers to their broadcaster managers. So they 84353358Sdim /// must be made into shared pointers, which you do with 85353358Sdim /// MakeBroadcasterManager. 86343181Sdim static lldb::BroadcasterManagerSP MakeBroadcasterManager(); 87343181Sdim 88343181Sdim ~BroadcasterManager() = default; 89343181Sdim 90343181Sdim uint32_t RegisterListenerForEvents(const lldb::ListenerSP &listener_sp, 91353358Sdim const BroadcastEventSpec &event_spec); 92343181Sdim 93343181Sdim bool UnregisterListenerForEvents(const lldb::ListenerSP &listener_sp, 94353358Sdim const BroadcastEventSpec &event_spec); 95343181Sdim 96353358Sdim lldb::ListenerSP 97353358Sdim GetListenerForEventSpec(const BroadcastEventSpec &event_spec) const; 98343181Sdim 99343181Sdim void SignUpListenersForBroadcaster(Broadcaster &broadcaster); 100343181Sdim 101343181Sdim void RemoveListener(const lldb::ListenerSP &listener_sp); 102343181Sdim 103343181Sdim void RemoveListener(Listener *listener); 104343181Sdim 105343181Sdim void Clear(); 106343181Sdim 107343181Sdimprivate: 108343181Sdim typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key; 109343181Sdim typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection; 110343181Sdim typedef std::set<lldb::ListenerSP> listener_collection; 111343181Sdim collection m_event_map; 112343181Sdim listener_collection m_listeners; 113343181Sdim 114343181Sdim mutable std::recursive_mutex m_manager_mutex; 115343181Sdim 116343181Sdim // A couple of comparator classes for find_if: 117343181Sdim 118343181Sdim class BroadcasterClassMatches { 119343181Sdim public: 120353358Sdim BroadcasterClassMatches(ConstString broadcaster_class) 121343181Sdim : m_broadcaster_class(broadcaster_class) {} 122343181Sdim 123343181Sdim ~BroadcasterClassMatches() = default; 124343181Sdim 125353358Sdim bool operator()(const event_listener_key &input) const { 126343181Sdim return (input.first.GetBroadcasterClass() == m_broadcaster_class); 127343181Sdim } 128343181Sdim 129343181Sdim private: 130343181Sdim ConstString m_broadcaster_class; 131343181Sdim }; 132343181Sdim 133343181Sdim class BroadcastEventSpecMatches { 134343181Sdim public: 135353358Sdim BroadcastEventSpecMatches(const BroadcastEventSpec &broadcaster_spec) 136343181Sdim : m_broadcaster_spec(broadcaster_spec) {} 137343181Sdim 138343181Sdim ~BroadcastEventSpecMatches() = default; 139343181Sdim 140353358Sdim bool operator()(const event_listener_key &input) const { 141343181Sdim return (input.first.IsContainedIn(m_broadcaster_spec)); 142343181Sdim } 143343181Sdim 144343181Sdim private: 145343181Sdim BroadcastEventSpec m_broadcaster_spec; 146343181Sdim }; 147343181Sdim 148343181Sdim class ListenerMatchesAndSharedBits { 149343181Sdim public: 150353358Sdim explicit ListenerMatchesAndSharedBits( 151353358Sdim const BroadcastEventSpec &broadcaster_spec, 152353358Sdim const lldb::ListenerSP &listener_sp) 153343181Sdim : m_broadcaster_spec(broadcaster_spec), m_listener_sp(listener_sp) {} 154343181Sdim 155343181Sdim ~ListenerMatchesAndSharedBits() = default; 156343181Sdim 157353358Sdim bool operator()(const event_listener_key &input) const { 158343181Sdim return (input.first.GetBroadcasterClass() == 159343181Sdim m_broadcaster_spec.GetBroadcasterClass() && 160343181Sdim (input.first.GetEventBits() & 161343181Sdim m_broadcaster_spec.GetEventBits()) != 0 && 162343181Sdim input.second == m_listener_sp); 163343181Sdim } 164343181Sdim 165343181Sdim private: 166343181Sdim BroadcastEventSpec m_broadcaster_spec; 167343181Sdim const lldb::ListenerSP m_listener_sp; 168343181Sdim }; 169343181Sdim 170343181Sdim class ListenerMatches { 171343181Sdim public: 172353358Sdim explicit ListenerMatches(const lldb::ListenerSP &in_listener_sp) 173343181Sdim : m_listener_sp(in_listener_sp) {} 174343181Sdim 175343181Sdim ~ListenerMatches() = default; 176343181Sdim 177353358Sdim bool operator()(const event_listener_key &input) const { 178343181Sdim if (input.second == m_listener_sp) 179343181Sdim return true; 180353358Sdim 181353358Sdim return false; 182343181Sdim } 183343181Sdim 184343181Sdim private: 185343181Sdim const lldb::ListenerSP m_listener_sp; 186343181Sdim }; 187343181Sdim 188343181Sdim class ListenerMatchesPointer { 189343181Sdim public: 190343181Sdim ListenerMatchesPointer(const Listener *in_listener) 191343181Sdim : m_listener(in_listener) {} 192343181Sdim 193343181Sdim ~ListenerMatchesPointer() = default; 194343181Sdim 195353358Sdim bool operator()(const event_listener_key &input) const { 196343181Sdim if (input.second.get() == m_listener) 197343181Sdim return true; 198353358Sdim 199353358Sdim return false; 200343181Sdim } 201343181Sdim 202353358Sdim bool operator()(const lldb::ListenerSP &input) const { 203343181Sdim if (input.get() == m_listener) 204343181Sdim return true; 205353358Sdim 206353358Sdim return false; 207343181Sdim } 208343181Sdim 209343181Sdim private: 210343181Sdim const Listener *m_listener; 211343181Sdim }; 212343181Sdim}; 213343181Sdim 214353358Sdim/// \class Broadcaster Broadcaster.h "lldb/Utility/Broadcaster.h" An event 215343181Sdim/// broadcasting class. 216343181Sdim/// 217343181Sdim/// The Broadcaster class is designed to be subclassed by objects that wish to 218343181Sdim/// vend events in a multi-threaded environment. Broadcaster objects can each 219343181Sdim/// vend 32 events. Each event is represented by a bit in a 32 bit value and 220343181Sdim/// these bits can be set: 221353358Sdim/// \see Broadcaster::SetEventBits(uint32_t) 222343181Sdim/// or cleared: 223353358Sdim/// \see Broadcaster::ResetEventBits(uint32_t) 224343181Sdim/// When an event gets set the Broadcaster object will notify the Listener 225343181Sdim/// object that is listening for the event (if there is one). 226343181Sdim/// 227343181Sdim/// Subclasses should provide broadcast bit definitions for any events they 228343181Sdim/// vend, typically using an enumeration: 229343181Sdim/// \code 230343181Sdim/// class Foo : public Broadcaster 231343181Sdim/// { 232343181Sdim/// public: 233343181Sdim/// // Broadcaster event bits definitions. 234343181Sdim/// enum 235343181Sdim/// { 236343181Sdim/// eBroadcastBitOne = (1 << 0), 237343181Sdim/// eBroadcastBitTwo = (1 << 1), 238343181Sdim/// eBroadcastBitThree = (1 << 2), 239343181Sdim/// ... 240343181Sdim/// }; 241343181Sdim/// \endcode 242343181Sdimclass Broadcaster { 243343181Sdim friend class Listener; 244343181Sdim friend class Event; 245343181Sdim 246343181Sdimpublic: 247343181Sdim /// Construct with a broadcaster with a name. 248343181Sdim /// 249353358Sdim /// \param[in] name 250343181Sdim /// A NULL terminated C string that contains the name of the 251343181Sdim /// broadcaster object. 252343181Sdim Broadcaster(lldb::BroadcasterManagerSP manager_sp, const char *name); 253343181Sdim 254343181Sdim /// Destructor. 255343181Sdim /// 256343181Sdim /// The destructor is virtual since this class gets subclassed. 257343181Sdim virtual ~Broadcaster(); 258343181Sdim 259343181Sdim void CheckInWithManager(); 260343181Sdim 261343181Sdim /// Broadcast an event which has no associated data. 262343181Sdim /// 263353358Sdim /// \param[in] event_type 264343181Sdim /// The element from the enum defining this broadcaster's events 265343181Sdim /// that is being broadcast. 266343181Sdim /// 267353358Sdim /// \param[in] event_data 268343181Sdim /// User event data that will be owned by the lldb::Event that 269343181Sdim /// is created internally. 270343181Sdim /// 271353358Sdim /// \param[in] unique 272343181Sdim /// If true, then only add an event of this type if there isn't 273343181Sdim /// one already in the queue. 274343181Sdim /// 275343181Sdim void BroadcastEvent(lldb::EventSP &event_sp) { 276343181Sdim m_broadcaster_sp->BroadcastEvent(event_sp); 277343181Sdim } 278343181Sdim 279343181Sdim void BroadcastEventIfUnique(lldb::EventSP &event_sp) { 280343181Sdim m_broadcaster_sp->BroadcastEventIfUnique(event_sp); 281343181Sdim } 282343181Sdim 283343181Sdim void BroadcastEvent(uint32_t event_type, 284343181Sdim const lldb::EventDataSP &event_data_sp) { 285343181Sdim m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp); 286343181Sdim } 287343181Sdim 288343181Sdim void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr) { 289343181Sdim m_broadcaster_sp->BroadcastEvent(event_type, event_data); 290343181Sdim } 291343181Sdim 292343181Sdim void BroadcastEventIfUnique(uint32_t event_type, 293343181Sdim EventData *event_data = nullptr) { 294343181Sdim m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data); 295343181Sdim } 296343181Sdim 297343181Sdim void Clear() { m_broadcaster_sp->Clear(); } 298343181Sdim 299343181Sdim virtual void AddInitialEventsToListener(const lldb::ListenerSP &listener_sp, 300343181Sdim uint32_t requested_events); 301343181Sdim 302343181Sdim /// Listen for any events specified by \a event_mask. 303343181Sdim /// 304343181Sdim /// Only one listener can listen to each event bit in a given Broadcaster. 305343181Sdim /// Once a listener has acquired an event bit, no other broadcaster will 306343181Sdim /// have access to it until it is relinquished by the first listener that 307343181Sdim /// gets it. The actual event bits that get acquired by \a listener may be 308343181Sdim /// different from what is requested in \a event_mask, and to track this the 309343181Sdim /// actual event bits that are acquired get returned. 310343181Sdim /// 311353358Sdim /// \param[in] listener 312343181Sdim /// The Listener object that wants to monitor the events that 313343181Sdim /// get broadcast by this object. 314343181Sdim /// 315353358Sdim /// \param[in] event_mask 316343181Sdim /// A bit mask that indicates which events the listener is 317343181Sdim /// asking to monitor. 318343181Sdim /// 319353358Sdim /// \return 320343181Sdim /// The actual event bits that were acquired by \a listener. 321343181Sdim uint32_t AddListener(const lldb::ListenerSP &listener_sp, 322343181Sdim uint32_t event_mask) { 323343181Sdim return m_broadcaster_sp->AddListener(listener_sp, event_mask); 324343181Sdim } 325343181Sdim 326343181Sdim /// Get the NULL terminated C string name of this Broadcaster object. 327343181Sdim /// 328353358Sdim /// \return 329343181Sdim /// The NULL terminated C string name of this Broadcaster. 330353358Sdim ConstString GetBroadcasterName() { return m_broadcaster_name; } 331343181Sdim 332343181Sdim /// Get the event name(s) for one or more event bits. 333343181Sdim /// 334353358Sdim /// \param[in] event_mask 335343181Sdim /// A bit mask that indicates which events to get names for. 336343181Sdim /// 337353358Sdim /// \return 338343181Sdim /// The NULL terminated C string name of this Broadcaster. 339343181Sdim bool GetEventNames(Stream &s, const uint32_t event_mask, 340343181Sdim bool prefix_with_broadcaster_name) const { 341343181Sdim return m_broadcaster_sp->GetEventNames(s, event_mask, 342343181Sdim prefix_with_broadcaster_name); 343343181Sdim } 344343181Sdim 345343181Sdim /// Set the name for an event bit. 346343181Sdim /// 347353358Sdim /// \param[in] event_mask 348343181Sdim /// A bit mask that indicates which events the listener is 349343181Sdim /// asking to monitor. 350343181Sdim /// 351353358Sdim /// \return 352343181Sdim /// The NULL terminated C string name of this Broadcaster. 353343181Sdim void SetEventName(uint32_t event_mask, const char *name) { 354343181Sdim m_broadcaster_sp->SetEventName(event_mask, name); 355343181Sdim } 356343181Sdim 357343181Sdim const char *GetEventName(uint32_t event_mask) const { 358343181Sdim return m_broadcaster_sp->GetEventName(event_mask); 359343181Sdim } 360343181Sdim 361343181Sdim bool EventTypeHasListeners(uint32_t event_type) { 362343181Sdim return m_broadcaster_sp->EventTypeHasListeners(event_type); 363343181Sdim } 364343181Sdim 365343181Sdim /// Removes a Listener from this broadcasters list and frees the event bits 366343181Sdim /// specified by \a event_mask that were previously acquired by \a listener 367343181Sdim /// (assuming \a listener was listening to this object) for other listener 368343181Sdim /// objects to use. 369343181Sdim /// 370353358Sdim /// \param[in] listener 371343181Sdim /// A Listener object that previously called AddListener. 372343181Sdim /// 373353358Sdim /// \param[in] event_mask 374343181Sdim /// The event bits \a listener wishes to relinquish. 375343181Sdim /// 376353358Sdim /// \return 377343181Sdim /// \b True if the listener was listening to this broadcaster 378343181Sdim /// and was removed, \b false otherwise. 379343181Sdim /// 380353358Sdim /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t) 381343181Sdim bool RemoveListener(const lldb::ListenerSP &listener_sp, 382343181Sdim uint32_t event_mask = UINT32_MAX) { 383343181Sdim return m_broadcaster_sp->RemoveListener(listener_sp, event_mask); 384343181Sdim } 385343181Sdim 386343181Sdim /// Provides a simple mechanism to temporarily redirect events from 387343181Sdim /// broadcaster. When you call this function passing in a listener and 388343181Sdim /// event type mask, all events from the broadcaster matching the mask will 389343181Sdim /// now go to the hijacking listener. Only one hijack can occur at a time. 390343181Sdim /// If we need more than this we will have to implement a Listener stack. 391343181Sdim /// 392353358Sdim /// \param[in] listener 393343181Sdim /// A Listener object. You do not need to call StartListeningForEvents 394343181Sdim /// for this broadcaster (that would fail anyway since the event bits 395343181Sdim /// would most likely be taken by the listener(s) you are usurping. 396343181Sdim /// 397353358Sdim /// \param[in] event_mask 398343181Sdim /// The event bits \a listener wishes to hijack. 399343181Sdim /// 400353358Sdim /// \return 401343181Sdim /// \b True if the event mask could be hijacked, \b false otherwise. 402343181Sdim /// 403353358Sdim /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t) 404343181Sdim bool HijackBroadcaster(const lldb::ListenerSP &listener_sp, 405343181Sdim uint32_t event_mask = UINT32_MAX) { 406343181Sdim return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask); 407343181Sdim } 408343181Sdim 409343181Sdim bool IsHijackedForEvent(uint32_t event_mask) { 410343181Sdim return m_broadcaster_sp->IsHijackedForEvent(event_mask); 411343181Sdim } 412343181Sdim 413343181Sdim /// Restore the state of the Broadcaster from a previous hijack attempt. 414343181Sdim void RestoreBroadcaster() { m_broadcaster_sp->RestoreBroadcaster(); } 415343181Sdim 416353358Sdim /// This needs to be filled in if you are going to register the broadcaster 417353358Sdim /// with the broadcaster manager and do broadcaster class matching. 418353358Sdim /// FIXME: Probably should make a ManagedBroadcaster subclass with all the 419353358Sdim /// bits needed to work with the BroadcasterManager, so that it is clearer 420353358Sdim /// how to add one. 421343181Sdim virtual ConstString &GetBroadcasterClass() const; 422343181Sdim 423343181Sdim lldb::BroadcasterManagerSP GetManager(); 424343181Sdim 425343181Sdimprotected: 426353358Sdim /// BroadcasterImpl contains the actual Broadcaster implementation. The 427353358Sdim /// Broadcaster makes a BroadcasterImpl which lives as long as it does. The 428353358Sdim /// Listeners & the Events hold a weak pointer to the BroadcasterImpl, so 429353358Sdim /// that they can survive if a Broadcaster they were listening to is 430353358Sdim /// destroyed w/o their being able to unregister from it (which can happen if 431353358Sdim /// the Broadcasters & Listeners are being destroyed on separate threads 432353358Sdim /// simultaneously. The Broadcaster itself can't be shared out as a weak 433353358Sdim /// pointer, because some things that are broadcasters (e.g. the Target and 434353358Sdim /// the Process) are shared in their own right. 435353358Sdim /// 436353358Sdim /// For the most part, the Broadcaster functions dispatch to the 437353358Sdim /// BroadcasterImpl, and are documented in the public Broadcaster API above. 438343181Sdim class BroadcasterImpl { 439343181Sdim friend class Listener; 440343181Sdim friend class Broadcaster; 441343181Sdim 442343181Sdim public: 443343181Sdim BroadcasterImpl(Broadcaster &broadcaster); 444343181Sdim 445343181Sdim ~BroadcasterImpl() = default; 446343181Sdim 447343181Sdim void BroadcastEvent(lldb::EventSP &event_sp); 448343181Sdim 449343181Sdim void BroadcastEventIfUnique(lldb::EventSP &event_sp); 450343181Sdim 451343181Sdim void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr); 452343181Sdim 453343181Sdim void BroadcastEvent(uint32_t event_type, 454343181Sdim const lldb::EventDataSP &event_data_sp); 455343181Sdim 456343181Sdim void BroadcastEventIfUnique(uint32_t event_type, 457343181Sdim EventData *event_data = nullptr); 458343181Sdim 459343181Sdim void Clear(); 460343181Sdim 461343181Sdim uint32_t AddListener(const lldb::ListenerSP &listener_sp, 462343181Sdim uint32_t event_mask); 463343181Sdim 464343181Sdim const char *GetBroadcasterName() const { 465343181Sdim return m_broadcaster.GetBroadcasterName().AsCString(); 466343181Sdim } 467343181Sdim 468343181Sdim Broadcaster *GetBroadcaster(); 469343181Sdim 470343181Sdim bool GetEventNames(Stream &s, const uint32_t event_mask, 471343181Sdim bool prefix_with_broadcaster_name) const; 472343181Sdim 473343181Sdim void SetEventName(uint32_t event_mask, const char *name) { 474343181Sdim m_event_names[event_mask] = name; 475343181Sdim } 476343181Sdim 477343181Sdim const char *GetEventName(uint32_t event_mask) const { 478343181Sdim const auto pos = m_event_names.find(event_mask); 479343181Sdim if (pos != m_event_names.end()) 480343181Sdim return pos->second.c_str(); 481343181Sdim return nullptr; 482343181Sdim } 483343181Sdim 484343181Sdim bool EventTypeHasListeners(uint32_t event_type); 485343181Sdim 486343181Sdim bool RemoveListener(lldb_private::Listener *listener, 487343181Sdim uint32_t event_mask = UINT32_MAX); 488343181Sdim 489343181Sdim bool RemoveListener(const lldb::ListenerSP &listener_sp, 490343181Sdim uint32_t event_mask = UINT32_MAX); 491343181Sdim 492343181Sdim bool HijackBroadcaster(const lldb::ListenerSP &listener_sp, 493343181Sdim uint32_t event_mask = UINT32_MAX); 494343181Sdim 495343181Sdim bool IsHijackedForEvent(uint32_t event_mask); 496343181Sdim 497343181Sdim void RestoreBroadcaster(); 498343181Sdim 499343181Sdim protected: 500343181Sdim void PrivateBroadcastEvent(lldb::EventSP &event_sp, bool unique); 501343181Sdim 502343181Sdim const char *GetHijackingListenerName(); 503343181Sdim 504343181Sdim typedef llvm::SmallVector<std::pair<lldb::ListenerWP, uint32_t>, 4> 505343181Sdim collection; 506343181Sdim typedef std::map<uint32_t, std::string> event_names_map; 507343181Sdim 508343181Sdim llvm::SmallVector<std::pair<lldb::ListenerSP, uint32_t &>, 4> 509343181Sdim GetListeners(); 510343181Sdim 511353358Sdim /// The broadcaster that this implements. 512353358Sdim Broadcaster &m_broadcaster; 513343181Sdim 514353358Sdim /// Optionally define event names for readability and logging for each 515353358Sdim /// event bit. 516353358Sdim event_names_map m_event_names; 517353358Sdim 518353358Sdim /// A list of Listener / event_mask pairs that are listening to this 519353358Sdim /// broadcaster. 520353358Sdim collection m_listeners; 521353358Sdim 522353358Sdim /// A mutex that protects \a m_listeners. 523353358Sdim std::recursive_mutex m_listeners_mutex; 524353358Sdim 525353358Sdim /// A simple mechanism to intercept events from a broadcaster 526353358Sdim std::vector<lldb::ListenerSP> m_hijacking_listeners; 527353358Sdim 528353358Sdim /// At some point we may want to have a stack or Listener collections, but 529353358Sdim /// for now this is just for private hijacking. 530353358Sdim std::vector<uint32_t> m_hijacking_masks; 531353358Sdim 532343181Sdim private: 533343181Sdim DISALLOW_COPY_AND_ASSIGN(BroadcasterImpl); 534343181Sdim }; 535343181Sdim 536343181Sdim typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP; 537343181Sdim typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP; 538343181Sdim 539343181Sdim BroadcasterImplSP GetBroadcasterImpl() { return m_broadcaster_sp; } 540343181Sdim 541343181Sdim const char *GetHijackingListenerName() { 542343181Sdim return m_broadcaster_sp->GetHijackingListenerName(); 543343181Sdim } 544343181Sdim 545343181Sdimprivate: 546343181Sdim BroadcasterImplSP m_broadcaster_sp; 547343181Sdim lldb::BroadcasterManagerSP m_manager_sp; 548343181Sdim 549353358Sdim /// The name of this broadcaster object. 550353358Sdim const ConstString m_broadcaster_name; 551353358Sdim 552343181Sdim DISALLOW_COPY_AND_ASSIGN(Broadcaster); 553343181Sdim}; 554343181Sdim 555343181Sdim} // namespace lldb_private 556343181Sdim 557343181Sdim#endif // LLDB_UTILITY_BROADCASTER_H 558