diff options
Diffstat (limited to 'include/lldb/Core/Broadcaster.h')
-rw-r--r-- | include/lldb/Core/Broadcaster.h | 1059 |
1 files changed, 491 insertions, 568 deletions
diff --git a/include/lldb/Core/Broadcaster.h b/include/lldb/Core/Broadcaster.h index 33172fa73780..c23f12c30b9c 100644 --- a/include/lldb/Core/Broadcaster.h +++ b/include/lldb/Core/Broadcaster.h @@ -21,8 +21,10 @@ // Other libraries and framework includes // Project includes -#include "lldb/lldb-private.h" #include "lldb/Core/ConstString.h" +#include "lldb/lldb-private.h" + +#include "llvm/ADT/SmallVector.h" namespace lldb_private { @@ -32,217 +34,181 @@ namespace lldb_private { // This class is used to specify a kind of event to register for. The Debugger // maintains a list of BroadcastEventSpec's and when it is made //---------------------------------------------------------------------- -class BroadcastEventSpec -{ +class BroadcastEventSpec { public: - BroadcastEventSpec (const ConstString &broadcaster_class, uint32_t event_bits) : - m_broadcaster_class (broadcaster_class), - m_event_bits (event_bits) - { - } - - BroadcastEventSpec (const BroadcastEventSpec &rhs); - - ~BroadcastEventSpec() = default; - - const ConstString &GetBroadcasterClass() const - { - return m_broadcaster_class; + BroadcastEventSpec(const ConstString &broadcaster_class, uint32_t event_bits) + : m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {} + + BroadcastEventSpec(const BroadcastEventSpec &rhs); + + ~BroadcastEventSpec() = default; + + const ConstString &GetBroadcasterClass() const { return m_broadcaster_class; } + + uint32_t GetEventBits() const { return m_event_bits; } + + // Tell whether this BroadcastEventSpec is contained in in_spec. + // That is: + // (a) the two spec's share the same broadcaster class + // (b) the event bits of this spec are wholly contained in those of in_spec. + bool IsContainedIn(BroadcastEventSpec in_spec) const { + if (m_broadcaster_class != in_spec.GetBroadcasterClass()) + return false; + uint32_t in_bits = in_spec.GetEventBits(); + if (in_bits == m_event_bits) + return true; + else { + if ((m_event_bits & in_bits) != 0 && (m_event_bits & ~in_bits) == 0) + return true; } - - uint32_t GetEventBits () const - { - return m_event_bits; - } - - // Tell whether this BroadcastEventSpec is contained in in_spec. - // That is: - // (a) the two spec's share the same broadcaster class - // (b) the event bits of this spec are wholly contained in those of in_spec. - bool IsContainedIn (BroadcastEventSpec in_spec) const - { - if (m_broadcaster_class != in_spec.GetBroadcasterClass()) - return false; - uint32_t in_bits = in_spec.GetEventBits(); - if (in_bits == m_event_bits) - return true; - else - { - if ((m_event_bits & in_bits) != 0 - && (m_event_bits & ~in_bits) == 0) - return true; - } - return false; - } - - bool operator< (const BroadcastEventSpec &rhs) const; - BroadcastEventSpec &operator=(const BroadcastEventSpec &rhs); - + return false; + } + + bool operator<(const BroadcastEventSpec &rhs) const; + BroadcastEventSpec &operator=(const BroadcastEventSpec &rhs); + private: - ConstString m_broadcaster_class; - uint32_t m_event_bits; + ConstString m_broadcaster_class; + uint32_t m_event_bits; }; -class BroadcasterManager : - public std::enable_shared_from_this<BroadcasterManager> -{ +class BroadcasterManager + : public std::enable_shared_from_this<BroadcasterManager> { public: - friend class Listener; + friend class Listener; protected: - BroadcasterManager (); + BroadcasterManager(); + public: - // Listeners hold onto weak pointers to their broadcaster managers. So they must be - // made into shared pointers, which you do with MakeBroadcasterManager. - - static lldb::BroadcasterManagerSP - MakeBroadcasterManager(); - - ~BroadcasterManager() = default; - - uint32_t - RegisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec); - - bool - UnregisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec); - - lldb::ListenerSP - GetListenerForEventSpec (BroadcastEventSpec event_spec) const; - - void - SignUpListenersForBroadcaster (Broadcaster &broadcaster); - - void - RemoveListener (const lldb::ListenerSP &listener_sp); - - void - RemoveListener (Listener *listener); + // Listeners hold onto weak pointers to their broadcaster managers. So they + // must be + // made into shared pointers, which you do with MakeBroadcasterManager. + + static lldb::BroadcasterManagerSP MakeBroadcasterManager(); + + ~BroadcasterManager() = default; + + uint32_t RegisterListenerForEvents(const lldb::ListenerSP &listener_sp, + BroadcastEventSpec event_spec); + + bool UnregisterListenerForEvents(const lldb::ListenerSP &listener_sp, + BroadcastEventSpec event_spec); + + lldb::ListenerSP GetListenerForEventSpec(BroadcastEventSpec event_spec) const; + + void SignUpListenersForBroadcaster(Broadcaster &broadcaster); + + void RemoveListener(const lldb::ListenerSP &listener_sp); + + void RemoveListener(Listener *listener); + + void Clear(); - void Clear(); - private: - typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key; - typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection; - typedef std::set<lldb::ListenerSP> listener_collection; - collection m_event_map; - listener_collection m_listeners; - - mutable std::recursive_mutex m_manager_mutex; - - // A couple of comparator classes for find_if: - - class BroadcasterClassMatches - { - public: - BroadcasterClassMatches (const ConstString &broadcaster_class) : - m_broadcaster_class (broadcaster_class) - { - } - - ~BroadcasterClassMatches() = default; - - bool operator() (const event_listener_key input) const - { - return (input.first.GetBroadcasterClass() == m_broadcaster_class); - } - - private: - ConstString m_broadcaster_class; - }; - - class BroadcastEventSpecMatches - { - public: - BroadcastEventSpecMatches (BroadcastEventSpec broadcaster_spec) : - m_broadcaster_spec (broadcaster_spec) - { - } - - ~BroadcastEventSpecMatches() = default; - - bool operator() (const event_listener_key input) const - { - return (input.first.IsContainedIn (m_broadcaster_spec)); - } - - private: - BroadcastEventSpec m_broadcaster_spec; - }; - - class ListenerMatchesAndSharedBits - { - public: - explicit ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec, const lldb::ListenerSP listener_sp) : - m_broadcaster_spec (broadcaster_spec), - m_listener_sp (listener_sp) - { - } - - ~ListenerMatchesAndSharedBits() = default; - - bool operator() (const event_listener_key input) const - { - return (input.first.GetBroadcasterClass() == m_broadcaster_spec.GetBroadcasterClass() - && (input.first.GetEventBits() & m_broadcaster_spec.GetEventBits()) != 0 - && input.second == m_listener_sp); - } - - private: - BroadcastEventSpec m_broadcaster_spec; - const lldb::ListenerSP m_listener_sp; - }; - - class ListenerMatches - { - public: - explicit ListenerMatches (const lldb::ListenerSP in_listener_sp) : - m_listener_sp (in_listener_sp) - { - } - - ~ListenerMatches() = default; - - bool operator () (const event_listener_key input) const - { - if (input.second == m_listener_sp) - return true; - else - return false; - } - - private: - const lldb::ListenerSP m_listener_sp; - }; - - class ListenerMatchesPointer - { - public: - ListenerMatchesPointer (const Listener *in_listener) : - m_listener (in_listener) - { - } - - ~ListenerMatchesPointer() = default; - - bool operator () (const event_listener_key input) const - { - if (input.second.get() == m_listener) - return true; - else - return false; - } - - bool operator () (const lldb::ListenerSP input) const - { - if (input.get() == m_listener) - return true; - else - return false; - } - - private: - const Listener *m_listener; - }; + typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key; + typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection; + typedef std::set<lldb::ListenerSP> listener_collection; + collection m_event_map; + listener_collection m_listeners; + + mutable std::recursive_mutex m_manager_mutex; + + // A couple of comparator classes for find_if: + + class BroadcasterClassMatches { + public: + BroadcasterClassMatches(const ConstString &broadcaster_class) + : m_broadcaster_class(broadcaster_class) {} + + ~BroadcasterClassMatches() = default; + + bool operator()(const event_listener_key input) const { + return (input.first.GetBroadcasterClass() == m_broadcaster_class); + } + + private: + ConstString m_broadcaster_class; + }; + + class BroadcastEventSpecMatches { + public: + BroadcastEventSpecMatches(BroadcastEventSpec broadcaster_spec) + : m_broadcaster_spec(broadcaster_spec) {} + + ~BroadcastEventSpecMatches() = default; + + bool operator()(const event_listener_key input) const { + return (input.first.IsContainedIn(m_broadcaster_spec)); + } + + private: + BroadcastEventSpec m_broadcaster_spec; + }; + + class ListenerMatchesAndSharedBits { + public: + explicit ListenerMatchesAndSharedBits(BroadcastEventSpec broadcaster_spec, + const lldb::ListenerSP listener_sp) + : m_broadcaster_spec(broadcaster_spec), m_listener_sp(listener_sp) {} + + ~ListenerMatchesAndSharedBits() = default; + + bool operator()(const event_listener_key input) const { + return (input.first.GetBroadcasterClass() == + m_broadcaster_spec.GetBroadcasterClass() && + (input.first.GetEventBits() & + m_broadcaster_spec.GetEventBits()) != 0 && + input.second == m_listener_sp); + } + + private: + BroadcastEventSpec m_broadcaster_spec; + const lldb::ListenerSP m_listener_sp; + }; + + class ListenerMatches { + public: + explicit ListenerMatches(const lldb::ListenerSP in_listener_sp) + : m_listener_sp(in_listener_sp) {} + + ~ListenerMatches() = default; + + bool operator()(const event_listener_key input) const { + if (input.second == m_listener_sp) + return true; + else + return false; + } + + private: + const lldb::ListenerSP m_listener_sp; + }; + + class ListenerMatchesPointer { + public: + ListenerMatchesPointer(const Listener *in_listener) + : m_listener(in_listener) {} + + ~ListenerMatchesPointer() = default; + + bool operator()(const event_listener_key input) const { + if (input.second.get() == m_listener) + return true; + else + return false; + } + + bool operator()(const lldb::ListenerSP input) const { + if (input.get() == m_listener) + return true; + else + return false; + } + + private: + const Listener *m_listener; + }; }; //---------------------------------------------------------------------- @@ -270,401 +236,358 @@ private: /// //---------------------------------------------------------- /// enum /// { -/// eBroadcastBitStateChanged = (1 << 0), -/// eBroadcastBitInterrupt = (1 << 1), -/// eBroadcastBitSTDOUT = (1 << 2), -/// eBroadcastBitSTDERR = (1 << 3), -/// eBroadcastBitProfileData = (1 << 4) +/// eBroadcastBitOne = (1 << 0), +/// eBroadcastBitTwo = (1 << 1), +/// eBroadcastBitThree = (1 << 2), +/// ... /// }; /// \endcode //---------------------------------------------------------------------- -class Broadcaster -{ -friend class Listener; -friend class Event; +class Broadcaster { + friend class Listener; + friend class Event; + public: - //------------------------------------------------------------------ - /// Construct with a broadcaster with a name. - /// - /// @param[in] name - /// A NULL terminated C string that contains the name of the - /// broadcaster object. - //------------------------------------------------------------------ - Broadcaster (lldb::BroadcasterManagerSP manager_sp, const char *name); + //------------------------------------------------------------------ + /// Construct with a broadcaster with a name. + /// + /// @param[in] name + /// A NULL terminated C string that contains the name of the + /// broadcaster object. + //------------------------------------------------------------------ + Broadcaster(lldb::BroadcasterManagerSP manager_sp, const char *name); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual since this class gets subclassed. + //------------------------------------------------------------------ + virtual ~Broadcaster(); + + void CheckInWithManager(); + + //------------------------------------------------------------------ + /// Broadcast an event which has no associated data. + /// + /// @param[in] event_type + /// The element from the enum defining this broadcaster's events + /// that is being broadcast. + /// + /// @param[in] event_data + /// User event data that will be owned by the lldb::Event that + /// is created internally. + /// + /// @param[in] unique + /// If true, then only add an event of this type if there isn't + /// one already in the queue. + /// + //------------------------------------------------------------------ + void BroadcastEvent(lldb::EventSP &event_sp) { + m_broadcaster_sp->BroadcastEvent(event_sp); + } + + void BroadcastEventIfUnique(lldb::EventSP &event_sp) { + m_broadcaster_sp->BroadcastEventIfUnique(event_sp); + } + + void BroadcastEvent(uint32_t event_type, + const lldb::EventDataSP &event_data_sp) { + m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp); + } + + void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr) { + m_broadcaster_sp->BroadcastEvent(event_type, event_data); + } + + void BroadcastEventIfUnique(uint32_t event_type, + EventData *event_data = nullptr) { + m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data); + } + + void Clear() { m_broadcaster_sp->Clear(); } + + virtual void AddInitialEventsToListener(const lldb::ListenerSP &listener_sp, + uint32_t requested_events); + + //------------------------------------------------------------------ + /// Listen for any events specified by \a event_mask. + /// + /// Only one listener can listen to each event bit in a given + /// Broadcaster. Once a listener has acquired an event bit, no + /// other broadcaster will have access to it until it is + /// relinquished by the first listener that gets it. The actual + /// event bits that get acquired by \a listener may be different + /// from what is requested in \a event_mask, and to track this the + /// actual event bits that are acquired get returned. + /// + /// @param[in] listener + /// The Listener object that wants to monitor the events that + /// get broadcast by this object. + /// + /// @param[in] event_mask + /// A bit mask that indicates which events the listener is + /// asking to monitor. + /// + /// @return + /// The actual event bits that were acquired by \a listener. + //------------------------------------------------------------------ + uint32_t AddListener(const lldb::ListenerSP &listener_sp, + uint32_t event_mask) { + return m_broadcaster_sp->AddListener(listener_sp, event_mask); + } + + //------------------------------------------------------------------ + /// Get the NULL terminated C string name of this Broadcaster + /// object. + /// + /// @return + /// The NULL terminated C string name of this Broadcaster. + //------------------------------------------------------------------ + const ConstString &GetBroadcasterName() { return m_broadcaster_name; } + + //------------------------------------------------------------------ + /// Get the event name(s) for one or more event bits. + /// + /// @param[in] event_mask + /// A bit mask that indicates which events to get names for. + /// + /// @return + /// The NULL terminated C string name of this Broadcaster. + //------------------------------------------------------------------ + bool GetEventNames(Stream &s, const uint32_t event_mask, + bool prefix_with_broadcaster_name) const { + return m_broadcaster_sp->GetEventNames(s, event_mask, + prefix_with_broadcaster_name); + } + + //------------------------------------------------------------------ + /// Set the name for an event bit. + /// + /// @param[in] event_mask + /// A bit mask that indicates which events the listener is + /// asking to monitor. + /// + /// @return + /// The NULL terminated C string name of this Broadcaster. + //------------------------------------------------------------------ + void SetEventName(uint32_t event_mask, const char *name) { + m_broadcaster_sp->SetEventName(event_mask, name); + } + + const char *GetEventName(uint32_t event_mask) const { + return m_broadcaster_sp->GetEventName(event_mask); + } + + bool EventTypeHasListeners(uint32_t event_type) { + return m_broadcaster_sp->EventTypeHasListeners(event_type); + } + + //------------------------------------------------------------------ + /// Removes a Listener from this broadcasters list and frees the + /// event bits specified by \a event_mask that were previously + /// acquired by \a listener (assuming \a listener was listening to + /// this object) for other listener objects to use. + /// + /// @param[in] listener + /// A Listener object that previously called AddListener. + /// + /// @param[in] event_mask + /// The event bits \a listener wishes to relinquish. + /// + /// @return + /// \b True if the listener was listening to this broadcaster + /// and was removed, \b false otherwise. + /// + /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t) + //------------------------------------------------------------------ + bool RemoveListener(const lldb::ListenerSP &listener_sp, + uint32_t event_mask = UINT32_MAX) { + return m_broadcaster_sp->RemoveListener(listener_sp, event_mask); + } + + //------------------------------------------------------------------ + /// Provides a simple mechanism to temporarily redirect events from + /// broadcaster. When you call this function passing in a listener and + /// event type mask, all events from the broadcaster matching the mask + /// will now go to the hijacking listener. + /// Only one hijack can occur at a time. If we need more than this we + /// will have to implement a Listener stack. + /// + /// @param[in] listener + /// A Listener object. You do not need to call StartListeningForEvents + /// for this broadcaster (that would fail anyway since the event bits + /// would most likely be taken by the listener(s) you are usurping. + /// + /// @param[in] event_mask + /// The event bits \a listener wishes to hijack. + /// + /// @return + /// \b True if the event mask could be hijacked, \b false otherwise. + /// + /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t) + //------------------------------------------------------------------ + bool HijackBroadcaster(const lldb::ListenerSP &listener_sp, + uint32_t event_mask = UINT32_MAX) { + return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask); + } + + bool IsHijackedForEvent(uint32_t event_mask) { + return m_broadcaster_sp->IsHijackedForEvent(event_mask); + } + + //------------------------------------------------------------------ + /// Restore the state of the Broadcaster from a previous hijack attempt. + /// + //------------------------------------------------------------------ + void RestoreBroadcaster() { m_broadcaster_sp->RestoreBroadcaster(); } + + // This needs to be filled in if you are going to register the broadcaster + // with the broadcaster + // manager and do broadcaster class matching. + // FIXME: Probably should make a ManagedBroadcaster subclass with all the bits + // needed to work + // with the BroadcasterManager, so that it is clearer how to add one. + virtual ConstString &GetBroadcasterClass() const; + + lldb::BroadcasterManagerSP GetManager(); - //------------------------------------------------------------------ - /// Destructor. - /// - /// The destructor is virtual since this class gets subclassed. - //------------------------------------------------------------------ - virtual - ~Broadcaster(); +protected: + // BroadcasterImpl contains the actual Broadcaster implementation. The + // Broadcaster makes a BroadcasterImpl + // which lives as long as it does. The Listeners & the Events hold a weak + // pointer to the BroadcasterImpl, + // so that they can survive if a Broadcaster they were listening to is + // destroyed w/o their being able to + // unregister from it (which can happen if the Broadcasters & Listeners are + // being destroyed on separate threads + // simultaneously. + // The Broadcaster itself can't be shared out as a weak pointer, because some + // things that are broadcasters + // (e.g. the Target and the Process) are shared in their own right. + // + // For the most part, the Broadcaster functions dispatch to the + // BroadcasterImpl, and are documented in the + // public Broadcaster API above. + + class BroadcasterImpl { + friend class Listener; + friend class Broadcaster; - void - CheckInWithManager (); - - //------------------------------------------------------------------ - /// Broadcast an event which has no associated data. - /// - /// @param[in] event_type - /// The element from the enum defining this broadcaster's events - /// that is being broadcast. - /// - /// @param[in] event_data - /// User event data that will be owned by the lldb::Event that - /// is created internally. - /// - /// @param[in] unique - /// If true, then only add an event of this type if there isn't - /// one already in the queue. - /// - //------------------------------------------------------------------ - void - BroadcastEvent (lldb::EventSP &event_sp) - { - m_broadcaster_sp->BroadcastEvent(event_sp); - } + public: + BroadcasterImpl(Broadcaster &broadcaster); - void - BroadcastEventIfUnique (lldb::EventSP &event_sp) - { - m_broadcaster_sp->BroadcastEventIfUnique(event_sp); - } + ~BroadcasterImpl() = default; - void - BroadcastEvent(uint32_t event_type, const lldb::EventDataSP &event_data_sp) - { - m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp); - } + void BroadcastEvent(lldb::EventSP &event_sp); - void - BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr) - { - m_broadcaster_sp->BroadcastEvent(event_type, event_data); - } + void BroadcastEventIfUnique(lldb::EventSP &event_sp); - void - BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr) - { - m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data); - } + void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr); - void - Clear() - { - m_broadcaster_sp->Clear(); - } + void BroadcastEvent(uint32_t event_type, + const lldb::EventDataSP &event_data_sp); - virtual void - AddInitialEventsToListener (const lldb::ListenerSP &listener_sp, uint32_t requested_events); + void BroadcastEventIfUnique(uint32_t event_type, + EventData *event_data = nullptr); - //------------------------------------------------------------------ - /// Listen for any events specified by \a event_mask. - /// - /// Only one listener can listen to each event bit in a given - /// Broadcaster. Once a listener has acquired an event bit, no - /// other broadcaster will have access to it until it is - /// relinquished by the first listener that gets it. The actual - /// event bits that get acquired by \a listener may be different - /// from what is requested in \a event_mask, and to track this the - /// actual event bits that are acquired get returned. - /// - /// @param[in] listener - /// The Listener object that wants to monitor the events that - /// get broadcast by this object. - /// - /// @param[in] event_mask - /// A bit mask that indicates which events the listener is - /// asking to monitor. - /// - /// @return - /// The actual event bits that were acquired by \a listener. - //------------------------------------------------------------------ - uint32_t - AddListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask) - { - return m_broadcaster_sp->AddListener(listener_sp, event_mask); - } + void Clear(); - //------------------------------------------------------------------ - /// Get the NULL terminated C string name of this Broadcaster - /// object. - /// - /// @return - /// The NULL terminated C string name of this Broadcaster. - //------------------------------------------------------------------ - const ConstString & - GetBroadcasterName () - { - return m_broadcaster_name; - } + uint32_t AddListener(const lldb::ListenerSP &listener_sp, + uint32_t event_mask); - //------------------------------------------------------------------ - /// Get the event name(s) for one or more event bits. - /// - /// @param[in] event_mask - /// A bit mask that indicates which events to get names for. - /// - /// @return - /// The NULL terminated C string name of this Broadcaster. - //------------------------------------------------------------------ - bool - GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const - { - return m_broadcaster_sp->GetEventNames(s, event_mask, prefix_with_broadcaster_name); + const char *GetBroadcasterName() const { + return m_broadcaster.GetBroadcasterName().AsCString(); } - //------------------------------------------------------------------ - /// Set the name for an event bit. - /// - /// @param[in] event_mask - /// A bit mask that indicates which events the listener is - /// asking to monitor. - /// - /// @return - /// The NULL terminated C string name of this Broadcaster. - //------------------------------------------------------------------ - void - SetEventName (uint32_t event_mask, const char *name) - { - m_broadcaster_sp->SetEventName(event_mask, name); - } - - const char * - GetEventName (uint32_t event_mask) const - { - return m_broadcaster_sp->GetEventName(event_mask); - } + Broadcaster *GetBroadcaster(); - bool - EventTypeHasListeners (uint32_t event_type) - { - return m_broadcaster_sp->EventTypeHasListeners(event_type); - } + bool GetEventNames(Stream &s, const uint32_t event_mask, + bool prefix_with_broadcaster_name) const; - //------------------------------------------------------------------ - /// Removes a Listener from this broadcasters list and frees the - /// event bits specified by \a event_mask that were previously - /// acquired by \a listener (assuming \a listener was listening to - /// this object) for other listener objects to use. - /// - /// @param[in] listener - /// A Listener object that previously called AddListener. - /// - /// @param[in] event_mask - /// The event bits \a listener wishes to relinquish. - /// - /// @return - /// \b True if the listener was listening to this broadcaster - /// and was removed, \b false otherwise. - /// - /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t) - //------------------------------------------------------------------ - bool - RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX) - { - return m_broadcaster_sp->RemoveListener(listener_sp, event_mask); - } - - //------------------------------------------------------------------ - /// Provides a simple mechanism to temporarily redirect events from - /// broadcaster. When you call this function passing in a listener and - /// event type mask, all events from the broadcaster matching the mask - /// will now go to the hijacking listener. - /// Only one hijack can occur at a time. If we need more than this we - /// will have to implement a Listener stack. - /// - /// @param[in] listener - /// A Listener object. You do not need to call StartListeningForEvents - /// for this broadcaster (that would fail anyway since the event bits - /// would most likely be taken by the listener(s) you are usurping. - /// - /// @param[in] event_mask - /// The event bits \a listener wishes to hijack. - /// - /// @return - /// \b True if the event mask could be hijacked, \b false otherwise. - /// - /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t) - //------------------------------------------------------------------ - bool - HijackBroadcaster (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX) - { - return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask); - } - - bool - IsHijackedForEvent (uint32_t event_mask) - { - return m_broadcaster_sp->IsHijackedForEvent(event_mask); + void SetEventName(uint32_t event_mask, const char *name) { + m_event_names[event_mask] = name; } - //------------------------------------------------------------------ - /// Restore the state of the Broadcaster from a previous hijack attempt. - /// - //------------------------------------------------------------------ - void - RestoreBroadcaster () - { - m_broadcaster_sp->RestoreBroadcaster(); + const char *GetEventName(uint32_t event_mask) const { + const auto pos = m_event_names.find(event_mask); + if (pos != m_event_names.end()) + return pos->second.c_str(); + return nullptr; } - - // This needs to be filled in if you are going to register the broadcaster with the broadcaster - // manager and do broadcaster class matching. - // FIXME: Probably should make a ManagedBroadcaster subclass with all the bits needed to work - // with the BroadcasterManager, so that it is clearer how to add one. - virtual ConstString &GetBroadcasterClass() const; - - lldb::BroadcasterManagerSP GetManager(); -protected: - // BroadcasterImpl contains the actual Broadcaster implementation. The Broadcaster makes a BroadcasterImpl - // which lives as long as it does. The Listeners & the Events hold a weak pointer to the BroadcasterImpl, - // so that they can survive if a Broadcaster they were listening to is destroyed w/o their being able to - // unregister from it (which can happen if the Broadcasters & Listeners are being destroyed on separate threads - // simultaneously. - // The Broadcaster itself can't be shared out as a weak pointer, because some things that are broadcasters - // (e.g. the Target and the Process) are shared in their own right. - // - // For the most part, the Broadcaster functions dispatch to the BroadcasterImpl, and are documented in the - // public Broadcaster API above. - - - class BroadcasterImpl - { - friend class Listener; - friend class Broadcaster; - public: - BroadcasterImpl (Broadcaster &broadcaster); - - ~BroadcasterImpl() = default; - - void - BroadcastEvent (lldb::EventSP &event_sp); - - void - BroadcastEventIfUnique (lldb::EventSP &event_sp); - - void - BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr); - - void - BroadcastEvent(uint32_t event_type, const lldb::EventDataSP &event_data_sp); - - void - BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr); - - void - Clear(); - - uint32_t - AddListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask); - - const char * - GetBroadcasterName () const - { - return m_broadcaster.GetBroadcasterName().AsCString(); - } - - Broadcaster * - GetBroadcaster(); - - bool - GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const; - - void - SetEventName (uint32_t event_mask, const char *name) - { - m_event_names[event_mask] = name; - } - - const char * - GetEventName (uint32_t event_mask) const - { - const auto pos = m_event_names.find (event_mask); - if (pos != m_event_names.end()) - return pos->second.c_str(); - return nullptr; - } - - bool - EventTypeHasListeners (uint32_t event_type); - - bool - RemoveListener (lldb_private::Listener *listener, uint32_t event_mask = UINT32_MAX); - - bool - RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX); - - bool - HijackBroadcaster (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX); - - bool - IsHijackedForEvent (uint32_t event_mask); - - void - RestoreBroadcaster (); - - protected: - void - PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique); - - const char * - GetHijackingListenerName(); - - //------------------------------------------------------------------ - // - //------------------------------------------------------------------ - typedef std::list< std::pair<lldb::ListenerWP,uint32_t> > collection; - typedef std::map<uint32_t, std::string> event_names_map; - - void - ListenerIterator (std::function <bool (const lldb::ListenerSP &listener_sp, uint32_t &event_mask)> const &callback); - - - Broadcaster &m_broadcaster; ///< The broadcsater that this implements - event_names_map m_event_names; ///< Optionally define event names for readability and logging for each event bit - collection m_listeners; ///< A list of Listener / event_mask pairs that are listening to this broadcaster. - std::recursive_mutex m_listeners_mutex; ///< A mutex that protects \a m_listeners. - std::vector<lldb::ListenerSP> m_hijacking_listeners; // A simple mechanism to intercept events from a broadcaster - std::vector<uint32_t> m_hijacking_masks; // At some point we may want to have a stack or Listener - // collections, but for now this is just for private hijacking. - - private: - //------------------------------------------------------------------ - // For Broadcaster only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (BroadcasterImpl); - }; - - typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP; - typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP; - - BroadcasterImplSP - GetBroadcasterImpl() - { - return m_broadcaster_sp; - } - - const char * - GetHijackingListenerName() - { - return m_broadcaster_sp->GetHijackingListenerName(); - } + bool EventTypeHasListeners(uint32_t event_type); + + bool RemoveListener(lldb_private::Listener *listener, + uint32_t event_mask = UINT32_MAX); + + bool RemoveListener(const lldb::ListenerSP &listener_sp, + uint32_t event_mask = UINT32_MAX); + + bool HijackBroadcaster(const lldb::ListenerSP &listener_sp, + uint32_t event_mask = UINT32_MAX); + + bool IsHijackedForEvent(uint32_t event_mask); + + void RestoreBroadcaster(); + + protected: + void PrivateBroadcastEvent(lldb::EventSP &event_sp, bool unique); + + const char *GetHijackingListenerName(); + //------------------------------------------------------------------ - // Classes that inherit from Broadcaster can see and modify these + // //------------------------------------------------------------------ - - -private: + typedef llvm::SmallVector<std::pair<lldb::ListenerWP, uint32_t>, 4> + collection; + typedef std::map<uint32_t, std::string> event_names_map; + + llvm::SmallVector<std::pair<lldb::ListenerSP, uint32_t &>, 4> + GetListeners(); + + Broadcaster &m_broadcaster; ///< The broadcsater that this implements + event_names_map m_event_names; ///< Optionally define event names for + ///readability and logging for each event bit + collection m_listeners; ///< A list of Listener / event_mask pairs that are + ///listening to this broadcaster. + std::recursive_mutex + m_listeners_mutex; ///< A mutex that protects \a m_listeners. + std::vector<lldb::ListenerSP> m_hijacking_listeners; // A simple mechanism + // to intercept events + // from a broadcaster + std::vector<uint32_t> m_hijacking_masks; // At some point we may want to + // have a stack or Listener + // collections, but for now this is just for private hijacking. + + private: //------------------------------------------------------------------ // For Broadcaster only //------------------------------------------------------------------ - BroadcasterImplSP m_broadcaster_sp; - lldb::BroadcasterManagerSP m_manager_sp; - const ConstString m_broadcaster_name; ///< The name of this broadcaster object. - - DISALLOW_COPY_AND_ASSIGN (Broadcaster); + DISALLOW_COPY_AND_ASSIGN(BroadcasterImpl); + }; + + typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP; + typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP; + + BroadcasterImplSP GetBroadcasterImpl() { return m_broadcaster_sp; } + + const char *GetHijackingListenerName() { + return m_broadcaster_sp->GetHijackingListenerName(); + } + //------------------------------------------------------------------ + // Classes that inherit from Broadcaster can see and modify these + //------------------------------------------------------------------ + +private: + //------------------------------------------------------------------ + // For Broadcaster only + //------------------------------------------------------------------ + BroadcasterImplSP m_broadcaster_sp; + lldb::BroadcasterManagerSP m_manager_sp; + const ConstString + m_broadcaster_name; ///< The name of this broadcaster object. + + DISALLOW_COPY_AND_ASSIGN(Broadcaster); }; } // namespace lldb_private |