Broadcaster.h revision 353358
1139825Simp//===-- Broadcaster.h -------------------------------------------*- C++ -*-===//
294755Sbenno//
394755Sbenno// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
494755Sbenno// See https://llvm.org/LICENSE.txt for license information.
594755Sbenno// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
694755Sbenno//
794755Sbenno//===----------------------------------------------------------------------===//
894755Sbenno
994755Sbenno#ifndef LLDB_UTILITY_BROADCASTER_H
1094755Sbenno#define LLDB_UTILITY_BROADCASTER_H
1194755Sbenno
1294755Sbenno#include "lldb/Utility/ConstString.h"
1394755Sbenno#include "lldb/lldb-defines.h"
1494755Sbenno#include "lldb/lldb-forward.h"
15125702Sgrehan
1694755Sbenno#include "llvm/ADT/SmallVector.h"
1794755Sbenno
1894755Sbenno#include <cstdint>
1994755Sbenno#include <map>
2094755Sbenno#include <memory>
2194755Sbenno#include <mutex>
2294755Sbenno#include <set>
2394755Sbenno#include <string>
2494755Sbenno#include <utility>
2594755Sbenno#include <vector>
2694755Sbenno
2794755Sbennonamespace lldb_private {
2894755Sbennoclass Broadcaster;
2994755Sbennoclass EventData;
3094755Sbennoclass Listener;
3194755Sbennoclass Stream;
3294755Sbenno} // namespace lldb_private
3394755Sbenno
3494755Sbennonamespace lldb_private {
3594755Sbenno
3694755Sbenno/// lldb::BroadcastEventSpec
3794755Sbenno///
3894755Sbenno/// This class is used to specify a kind of event to register for.  The
3994755Sbenno/// Debugger maintains a list of BroadcastEventSpec's and when it is made
4094755Sbennoclass BroadcastEventSpec {
4194755Sbennopublic:
4294755Sbenno  BroadcastEventSpec(ConstString broadcaster_class, uint32_t event_bits)
4394755Sbenno      : m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {}
4494755Sbenno
4594755Sbenno  ~BroadcastEventSpec() = default;
4694755Sbenno
4794755Sbenno  ConstString GetBroadcasterClass() const { return m_broadcaster_class; }
4894755Sbenno
4994755Sbenno  uint32_t GetEventBits() const { return m_event_bits; }
5094755Sbenno
5194755Sbenno  /// Tell whether this BroadcastEventSpec is contained in in_spec. That is:
5294755Sbenno  /// (a) the two spec's share the same broadcaster class (b) the event bits of
5394755Sbenno  /// this spec are wholly contained in those of in_spec.
5494755Sbenno  bool IsContainedIn(const BroadcastEventSpec &in_spec) const {
5594755Sbenno    if (m_broadcaster_class != in_spec.GetBroadcasterClass())
5694755Sbenno      return false;
57103601Sgrehan    uint32_t in_bits = in_spec.GetEventBits();
5894755Sbenno    if (in_bits == m_event_bits)
5994755Sbenno      return true;
6094755Sbenno
61131102Sgrehan    if ((m_event_bits & in_bits) != 0 && (m_event_bits & ~in_bits) == 0)
6294755Sbenno      return true;
6394755Sbenno
6494755Sbenno    return false;
6594755Sbenno  }
6694755Sbenno
6794755Sbenno  bool operator<(const BroadcastEventSpec &rhs) const;
6894755Sbenno  BroadcastEventSpec &operator=(const BroadcastEventSpec &rhs);
6994755Sbenno
7094755Sbennoprivate:
7199652Sbenno  ConstString m_broadcaster_class;
7294755Sbenno  uint32_t m_event_bits;
7394755Sbenno};
7494755Sbenno
7599652Sbennoclass BroadcasterManager
7699652Sbenno    : public std::enable_shared_from_this<BroadcasterManager> {
77168885Sgrehanpublic:
7899652Sbenno  friend class Listener;
7999652Sbenno
8094755Sbennoprotected:
8194755Sbenno  BroadcasterManager();
82133862Smarius
8394755Sbennopublic:
8494755Sbenno  /// Listeners hold onto weak pointers to their broadcaster managers.  So they
8594755Sbenno  /// must be made into shared pointers, which you do with
86133862Smarius  /// MakeBroadcasterManager.
8794755Sbenno  static lldb::BroadcasterManagerSP MakeBroadcasterManager();
8894755Sbenno
8994755Sbenno  ~BroadcasterManager() = default;
9094755Sbenno
9194755Sbenno  uint32_t RegisterListenerForEvents(const lldb::ListenerSP &listener_sp,
9294755Sbenno                                     const BroadcastEventSpec &event_spec);
9394755Sbenno
94125702Sgrehan  bool UnregisterListenerForEvents(const lldb::ListenerSP &listener_sp,
95125702Sgrehan                                   const BroadcastEventSpec &event_spec);
96125702Sgrehan
9794755Sbenno  lldb::ListenerSP
9894755Sbenno  GetListenerForEventSpec(const BroadcastEventSpec &event_spec) const;
9994755Sbenno
100171805Smarcel  void SignUpListenersForBroadcaster(Broadcaster &broadcaster);
10194755Sbenno
10294755Sbenno  void RemoveListener(const lldb::ListenerSP &listener_sp);
10399652Sbenno
10499652Sbenno  void RemoveListener(Listener *listener);
10599652Sbenno
10699652Sbenno  void Clear();
10799652Sbenno
10894755Sbennoprivate:
10999652Sbenno  typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key;
11099652Sbenno  typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection;
11199652Sbenno  typedef std::set<lldb::ListenerSP> listener_collection;
112124468Sgrehan  collection m_event_map;
11399652Sbenno  listener_collection m_listeners;
11499652Sbenno
11599652Sbenno  mutable std::recursive_mutex m_manager_mutex;
116167289Spiso
11799652Sbenno  // A couple of comparator classes for find_if:
11899652Sbenno
11999652Sbenno  class BroadcasterClassMatches {
12099652Sbenno  public:
12199652Sbenno    BroadcasterClassMatches(ConstString broadcaster_class)
12299652Sbenno        : m_broadcaster_class(broadcaster_class) {}
12399652Sbenno
12499652Sbenno    ~BroadcasterClassMatches() = default;
12599652Sbenno
12699652Sbenno    bool operator()(const event_listener_key &input) const {
12799652Sbenno      return (input.first.GetBroadcasterClass() == m_broadcaster_class);
128168885Sgrehan    }
129168885Sgrehan
130168885Sgrehan  private:
131168885Sgrehan    ConstString m_broadcaster_class;
132168885Sgrehan  };
13399652Sbenno
13499652Sbenno  class BroadcastEventSpecMatches {
13599652Sbenno  public:
136124468Sgrehan    BroadcastEventSpecMatches(const BroadcastEventSpec &broadcaster_spec)
13799652Sbenno        : m_broadcaster_spec(broadcaster_spec) {}
13894755Sbenno
13994755Sbenno    ~BroadcastEventSpecMatches() = default;
14094755Sbenno
14194755Sbenno    bool operator()(const event_listener_key &input) const {
14294755Sbenno      return (input.first.IsContainedIn(m_broadcaster_spec));
14394755Sbenno    }
14494755Sbenno
14594755Sbenno  private:
14694755Sbenno    BroadcastEventSpec m_broadcaster_spec;
14794755Sbenno  };
148124468Sgrehan
14994755Sbenno  class ListenerMatchesAndSharedBits {
15094755Sbenno  public:
15194755Sbenno    explicit ListenerMatchesAndSharedBits(
15294755Sbenno        const BroadcastEventSpec &broadcaster_spec,
15399652Sbenno        const lldb::ListenerSP &listener_sp)
15499652Sbenno        : m_broadcaster_spec(broadcaster_spec), m_listener_sp(listener_sp) {}
15599652Sbenno
15699652Sbenno    ~ListenerMatchesAndSharedBits() = default;
15799652Sbenno
15899652Sbenno    bool operator()(const event_listener_key &input) const {
15994755Sbenno      return (input.first.GetBroadcasterClass() ==
160168885Sgrehan                  m_broadcaster_spec.GetBroadcasterClass() &&
161168885Sgrehan              (input.first.GetEventBits() &
162168885Sgrehan               m_broadcaster_spec.GetEventBits()) != 0 &&
163168885Sgrehan              input.second == m_listener_sp);
164168885Sgrehan    }
165168885Sgrehan
16694755Sbenno  private:
16794755Sbenno    BroadcastEventSpec m_broadcaster_spec;
16894755Sbenno    const lldb::ListenerSP m_listener_sp;
16994755Sbenno  };
17094755Sbenno
17194755Sbenno  class ListenerMatches {
17294755Sbenno  public:
17394755Sbenno    explicit ListenerMatches(const lldb::ListenerSP &in_listener_sp)
17494755Sbenno        : m_listener_sp(in_listener_sp) {}
17594755Sbenno
17694755Sbenno    ~ListenerMatches() = default;
17794755Sbenno
17894755Sbenno    bool operator()(const event_listener_key &input) const {
17994755Sbenno      if (input.second == m_listener_sp)
18094755Sbenno        return true;
18194755Sbenno
18294755Sbenno      return false;
183124468Sgrehan    }
18494755Sbenno
185171805Smarcel  private:
18694755Sbenno    const lldb::ListenerSP m_listener_sp;
18794755Sbenno  };
18894755Sbenno
18994755Sbenno  class ListenerMatchesPointer {
19099652Sbenno  public:
19199652Sbenno    ListenerMatchesPointer(const Listener *in_listener)
192171805Smarcel        : m_listener(in_listener) {}
193171805Smarcel
194171805Smarcel    ~ListenerMatchesPointer() = default;
195171805Smarcel
196171805Smarcel    bool operator()(const event_listener_key &input) const {
197171805Smarcel      if (input.second.get() == m_listener)
198171805Smarcel        return true;
199171805Smarcel
200171805Smarcel      return false;
201171805Smarcel    }
202171805Smarcel
203124468Sgrehan    bool operator()(const lldb::ListenerSP &input) const {
204124468Sgrehan      if (input.get() == m_listener)
205124468Sgrehan        return true;
206124468Sgrehan
207125702Sgrehan      return false;
208124468Sgrehan    }
209124468Sgrehan
210124468Sgrehan  private:
211124468Sgrehan    const Listener *m_listener;
212124468Sgrehan  };
213124468Sgrehan};
214124468Sgrehan
21599652Sbenno/// \class Broadcaster Broadcaster.h "lldb/Utility/Broadcaster.h" An event
21694755Sbenno/// broadcasting class.
217133862Smarius///
21894755Sbenno/// The Broadcaster class is designed to be subclassed by objects that wish to
21994755Sbenno/// vend events in a multi-threaded environment. Broadcaster objects can each
22094755Sbenno/// vend 32 events. Each event is represented by a bit in a 32 bit value and
22194755Sbenno/// these bits can be set:
22294755Sbenno///     \see Broadcaster::SetEventBits(uint32_t)
22394755Sbenno/// or cleared:
22494755Sbenno///     \see Broadcaster::ResetEventBits(uint32_t)
22594755Sbenno/// When an event gets set the Broadcaster object will notify the Listener
22694755Sbenno/// object that is listening for the event (if there is one).
22794755Sbenno///
22894755Sbenno/// Subclasses should provide broadcast bit definitions for any events they
22994755Sbenno/// vend, typically using an enumeration:
23094755Sbenno///     \code
23194755Sbenno///         class Foo : public Broadcaster
23294755Sbenno///         {
23394755Sbenno///         public:
234124468Sgrehan///         // Broadcaster event bits definitions.
235124468Sgrehan///         enum
236124468Sgrehan///         {
237124468Sgrehan///             eBroadcastBitOne   = (1 << 0),
23894755Sbenno///             eBroadcastBitTwo   = (1 << 1),
23994755Sbenno///             eBroadcastBitThree = (1 << 2),
240124468Sgrehan///             ...
241124468Sgrehan///         };
242124468Sgrehan///     \endcode
243124468Sgrehanclass Broadcaster {
244124468Sgrehan  friend class Listener;
245124468Sgrehan  friend class Event;
246124468Sgrehan
247125702Sgrehanpublic:
248124468Sgrehan  /// Construct with a broadcaster with a name.
249125702Sgrehan  ///
250124468Sgrehan  /// \param[in] name
251124468Sgrehan  ///     A NULL terminated C string that contains the name of the
252124468Sgrehan  ///     broadcaster object.
253124468Sgrehan  Broadcaster(lldb::BroadcasterManagerSP manager_sp, const char *name);
254124468Sgrehan
255124468Sgrehan  /// Destructor.
256125702Sgrehan  ///
257125702Sgrehan  /// The destructor is virtual since this class gets subclassed.
258124468Sgrehan  virtual ~Broadcaster();
259124468Sgrehan
260124468Sgrehan  void CheckInWithManager();
261124468Sgrehan
26294755Sbenno  /// Broadcast an event which has no associated data.
26394755Sbenno  ///
26494755Sbenno  /// \param[in] event_type
26594755Sbenno  ///     The element from the enum defining this broadcaster's events
26694755Sbenno  ///     that is being broadcast.
26794755Sbenno  ///
26894755Sbenno  /// \param[in] event_data
26994755Sbenno  ///     User event data that will be owned by the lldb::Event that
27094755Sbenno  ///     is created internally.
27194755Sbenno  ///
27294755Sbenno  /// \param[in] unique
27394755Sbenno  ///     If true, then only add an event of this type if there isn't
27494755Sbenno  ///     one already in the queue.
27594755Sbenno  ///
27694755Sbenno  void BroadcastEvent(lldb::EventSP &event_sp) {
27794755Sbenno    m_broadcaster_sp->BroadcastEvent(event_sp);
27894755Sbenno  }
27999652Sbenno
28099652Sbenno  void BroadcastEventIfUnique(lldb::EventSP &event_sp) {
28199652Sbenno    m_broadcaster_sp->BroadcastEventIfUnique(event_sp);
28294755Sbenno  }
28394755Sbenno
28494755Sbenno  void BroadcastEvent(uint32_t event_type,
28594755Sbenno                      const lldb::EventDataSP &event_data_sp) {
28694755Sbenno    m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp);
28794755Sbenno  }
28894755Sbenno
28994755Sbenno  void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr) {
29094755Sbenno    m_broadcaster_sp->BroadcastEvent(event_type, event_data);
29194755Sbenno  }
29294755Sbenno
29394755Sbenno  void BroadcastEventIfUnique(uint32_t event_type,
29494755Sbenno                              EventData *event_data = nullptr) {
29594755Sbenno    m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data);
29694755Sbenno  }
29794755Sbenno
298124468Sgrehan  void Clear() { m_broadcaster_sp->Clear(); }
299124468Sgrehan
300125434Sgrehan  virtual void AddInitialEventsToListener(const lldb::ListenerSP &listener_sp,
301125434Sgrehan                                          uint32_t requested_events);
302125434Sgrehan
303125434Sgrehan  /// Listen for any events specified by \a event_mask.
304125434Sgrehan  ///
30594755Sbenno  /// Only one listener can listen to each event bit in a given Broadcaster.
306124468Sgrehan  /// Once a listener has acquired an event bit, no other broadcaster will
307124468Sgrehan  /// have access to it until it is relinquished by the first listener that
308124468Sgrehan  /// gets it. The actual event bits that get acquired by \a listener may be
30994755Sbenno  /// different from what is requested in \a event_mask, and to track this the
31094755Sbenno  /// actual event bits that are acquired get returned.
31194755Sbenno  ///
31294755Sbenno  /// \param[in] listener
31394755Sbenno  ///     The Listener object that wants to monitor the events that
31499652Sbenno  ///     get broadcast by this object.
31599652Sbenno  ///
31699652Sbenno  /// \param[in] event_mask
317171805Smarcel  ///     A bit mask that indicates which events the listener is
31899652Sbenno  ///     asking to monitor.
319171805Smarcel  ///
320171805Smarcel  /// \return
32199652Sbenno  ///     The actual event bits that were acquired by \a listener.
322171805Smarcel  uint32_t AddListener(const lldb::ListenerSP &listener_sp,
323171805Smarcel                       uint32_t event_mask) {
324171805Smarcel    return m_broadcaster_sp->AddListener(listener_sp, event_mask);
32599652Sbenno  }
326171805Smarcel
327171805Smarcel  /// Get the NULL terminated C string name of this Broadcaster object.
328171805Smarcel  ///
32999652Sbenno  /// \return
330171805Smarcel  ///     The NULL terminated C string name of this Broadcaster.
331171805Smarcel  ConstString GetBroadcasterName() { return m_broadcaster_name; }
332171805Smarcel
333171805Smarcel  /// Get the event name(s) for one or more event bits.
334171805Smarcel  ///
335171805Smarcel  /// \param[in] event_mask
336171805Smarcel  ///     A bit mask that indicates which events to get names for.
337171805Smarcel  ///
338171805Smarcel  /// \return
339171805Smarcel  ///     The NULL terminated C string name of this Broadcaster.
340171805Smarcel  bool GetEventNames(Stream &s, const uint32_t event_mask,
341171805Smarcel                     bool prefix_with_broadcaster_name) const {
342171805Smarcel    return m_broadcaster_sp->GetEventNames(s, event_mask,
34399652Sbenno                                           prefix_with_broadcaster_name);
34499652Sbenno  }
34599652Sbenno
34699652Sbenno  /// Set the name for an event bit.
347171805Smarcel  ///
34899652Sbenno  /// \param[in] event_mask
34999652Sbenno  ///     A bit mask that indicates which events the listener is
350171805Smarcel  ///     asking to monitor.
35199652Sbenno  ///
35299652Sbenno  /// \return
35399652Sbenno  ///     The NULL terminated C string name of this Broadcaster.
35499652Sbenno  void SetEventName(uint32_t event_mask, const char *name) {
35599652Sbenno    m_broadcaster_sp->SetEventName(event_mask, name);
35699652Sbenno  }
35799652Sbenno
35899652Sbenno  const char *GetEventName(uint32_t event_mask) const {
35999652Sbenno    return m_broadcaster_sp->GetEventName(event_mask);
36099652Sbenno  }
361171805Smarcel
362171805Smarcel  bool EventTypeHasListeners(uint32_t event_type) {
36399652Sbenno    return m_broadcaster_sp->EventTypeHasListeners(event_type);
36499652Sbenno  }
36599652Sbenno
36699652Sbenno  /// Removes a Listener from this broadcasters list and frees the event bits
36799652Sbenno  /// specified by \a event_mask that were previously acquired by \a listener
36899652Sbenno  /// (assuming \a listener was listening to this object) for other listener
36999652Sbenno  /// objects to use.
370171805Smarcel  ///
371171805Smarcel  /// \param[in] listener
372171805Smarcel  ///     A Listener object that previously called AddListener.
373171805Smarcel  ///
374171805Smarcel  /// \param[in] event_mask
37599652Sbenno  ///     The event bits \a listener wishes to relinquish.
376171805Smarcel  ///
37799652Sbenno  /// \return
378171805Smarcel  ///     \b True if the listener was listening to this broadcaster
379171805Smarcel  ///     and was removed, \b false otherwise.
380171805Smarcel  ///
381171805Smarcel  /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
382171805Smarcel  bool RemoveListener(const lldb::ListenerSP &listener_sp,
383171805Smarcel                      uint32_t event_mask = UINT32_MAX) {
384171805Smarcel    return m_broadcaster_sp->RemoveListener(listener_sp, event_mask);
385171805Smarcel  }
38699652Sbenno
38799652Sbenno  /// Provides a simple mechanism to temporarily redirect events from
38899652Sbenno  /// broadcaster.  When you call this function passing in a listener and
38999652Sbenno  /// event type mask, all events from the broadcaster matching the mask will
39099652Sbenno  /// now go to the hijacking listener. Only one hijack can occur at a time.
39199652Sbenno  /// If we need more than this we will have to implement a Listener stack.
39299652Sbenno  ///
39399652Sbenno  /// \param[in] listener
39499652Sbenno  ///     A Listener object.  You do not need to call StartListeningForEvents
39599652Sbenno  ///     for this broadcaster (that would fail anyway since the event bits
39699652Sbenno  ///     would most likely be taken by the listener(s) you are usurping.
39799652Sbenno  ///
39899652Sbenno  /// \param[in] event_mask
39999652Sbenno  ///     The event bits \a listener wishes to hijack.
40099652Sbenno  ///
40199652Sbenno  /// \return
40299652Sbenno  ///     \b True if the event mask could be hijacked, \b false otherwise.
40399652Sbenno  ///
40499652Sbenno  /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
40599652Sbenno  bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
40699652Sbenno                         uint32_t event_mask = UINT32_MAX) {
40799652Sbenno    return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask);
40899652Sbenno  }
40999652Sbenno
41099652Sbenno  bool IsHijackedForEvent(uint32_t event_mask) {
41199652Sbenno    return m_broadcaster_sp->IsHijackedForEvent(event_mask);
41299652Sbenno  }
41399652Sbenno
41499652Sbenno  /// Restore the state of the Broadcaster from a previous hijack attempt.
415124468Sgrehan  void RestoreBroadcaster() { m_broadcaster_sp->RestoreBroadcaster(); }
41699652Sbenno
41799652Sbenno  /// This needs to be filled in if you are going to register the broadcaster
418171805Smarcel  /// with the broadcaster manager and do broadcaster class matching.
41999652Sbenno  /// FIXME: Probably should make a ManagedBroadcaster subclass with all the
42099652Sbenno  /// bits needed to work with the BroadcasterManager, so that it is clearer
42199652Sbenno  /// how to add one.
422124468Sgrehan  virtual ConstString &GetBroadcasterClass() const;
42399652Sbenno
42499652Sbenno  lldb::BroadcasterManagerSP GetManager();
42599652Sbenno
42699652Sbennoprotected:
42799652Sbenno  /// BroadcasterImpl contains the actual Broadcaster implementation.  The
42899652Sbenno  /// Broadcaster makes a BroadcasterImpl which lives as long as it does.  The
42999652Sbenno  /// Listeners & the Events hold a weak pointer to the BroadcasterImpl, so
43099652Sbenno  /// that they can survive if a Broadcaster they were listening to is
43199652Sbenno  /// destroyed w/o their being able to unregister from it (which can happen if
43299652Sbenno  /// the Broadcasters & Listeners are being destroyed on separate threads
433111119Simp  /// simultaneously. The Broadcaster itself can't be shared out as a weak
43499652Sbenno  /// pointer, because some things that are broadcasters (e.g. the Target and
43599652Sbenno  /// the Process) are shared in their own right.
43699652Sbenno  ///
43799652Sbenno  /// For the most part, the Broadcaster functions dispatch to the
43899652Sbenno  /// BroadcasterImpl, and are documented in the public Broadcaster API above.
43999652Sbenno  class BroadcasterImpl {
44099652Sbenno    friend class Listener;
44199652Sbenno    friend class Broadcaster;
44299652Sbenno
44399652Sbenno  public:
444124468Sgrehan    BroadcasterImpl(Broadcaster &broadcaster);
445168885Sgrehan
446168885Sgrehan    ~BroadcasterImpl() = default;
447168885Sgrehan
448168885Sgrehan    void BroadcastEvent(lldb::EventSP &event_sp);
449168885Sgrehan
450168885Sgrehan    void BroadcastEventIfUnique(lldb::EventSP &event_sp);
451168885Sgrehan
452168885Sgrehan    void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr);
453168885Sgrehan
454168885Sgrehan    void BroadcastEvent(uint32_t event_type,
455168885Sgrehan                        const lldb::EventDataSP &event_data_sp);
456168885Sgrehan
457168885Sgrehan    void BroadcastEventIfUnique(uint32_t event_type,
458168885Sgrehan                                EventData *event_data = nullptr);
459168885Sgrehan
460168885Sgrehan    void Clear();
461168885Sgrehan
462168885Sgrehan    uint32_t AddListener(const lldb::ListenerSP &listener_sp,
463168885Sgrehan                         uint32_t event_mask);
464168885Sgrehan
465168885Sgrehan    const char *GetBroadcasterName() const {
466168885Sgrehan      return m_broadcaster.GetBroadcasterName().AsCString();
467168885Sgrehan    }
468168885Sgrehan
469168885Sgrehan    Broadcaster *GetBroadcaster();
470168885Sgrehan
471168885Sgrehan    bool GetEventNames(Stream &s, const uint32_t event_mask,
472168885Sgrehan                       bool prefix_with_broadcaster_name) const;
473168885Sgrehan
474168885Sgrehan    void SetEventName(uint32_t event_mask, const char *name) {
475168885Sgrehan      m_event_names[event_mask] = name;
476168885Sgrehan    }
477168885Sgrehan
478168885Sgrehan    const char *GetEventName(uint32_t event_mask) const {
479168885Sgrehan      const auto pos = m_event_names.find(event_mask);
480168885Sgrehan      if (pos != m_event_names.end())
481168885Sgrehan        return pos->second.c_str();
482168885Sgrehan      return nullptr;
483168885Sgrehan    }
484168885Sgrehan
485168885Sgrehan    bool EventTypeHasListeners(uint32_t event_type);
486168885Sgrehan
487168885Sgrehan    bool RemoveListener(lldb_private::Listener *listener,
488                        uint32_t event_mask = UINT32_MAX);
489
490    bool RemoveListener(const lldb::ListenerSP &listener_sp,
491                        uint32_t event_mask = UINT32_MAX);
492
493    bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
494                           uint32_t event_mask = UINT32_MAX);
495
496    bool IsHijackedForEvent(uint32_t event_mask);
497
498    void RestoreBroadcaster();
499
500  protected:
501    void PrivateBroadcastEvent(lldb::EventSP &event_sp, bool unique);
502
503    const char *GetHijackingListenerName();
504
505    typedef llvm::SmallVector<std::pair<lldb::ListenerWP, uint32_t>, 4>
506        collection;
507    typedef std::map<uint32_t, std::string> event_names_map;
508
509    llvm::SmallVector<std::pair<lldb::ListenerSP, uint32_t &>, 4>
510    GetListeners();
511
512    /// The broadcaster that this implements.
513    Broadcaster &m_broadcaster;
514
515    /// Optionally define event names for readability and logging for each
516    /// event bit.
517    event_names_map m_event_names;
518
519    /// A list of Listener / event_mask pairs that are listening to this
520    /// broadcaster.
521    collection m_listeners;
522
523    /// A mutex that protects \a m_listeners.
524    std::recursive_mutex m_listeners_mutex;
525
526    /// A simple mechanism to intercept events from a broadcaster
527    std::vector<lldb::ListenerSP> m_hijacking_listeners;
528
529    /// At some point we may want to have a stack or Listener collections, but
530    /// for now this is just for private hijacking.
531    std::vector<uint32_t> m_hijacking_masks;
532
533  private:
534    DISALLOW_COPY_AND_ASSIGN(BroadcasterImpl);
535  };
536
537  typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP;
538  typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP;
539
540  BroadcasterImplSP GetBroadcasterImpl() { return m_broadcaster_sp; }
541
542  const char *GetHijackingListenerName() {
543    return m_broadcaster_sp->GetHijackingListenerName();
544  }
545
546private:
547  BroadcasterImplSP m_broadcaster_sp;
548  lldb::BroadcasterManagerSP m_manager_sp;
549
550  /// The name of this broadcaster object.
551  const ConstString m_broadcaster_name;
552
553  DISALLOW_COPY_AND_ASSIGN(Broadcaster);
554};
555
556} // namespace lldb_private
557
558#endif // LLDB_UTILITY_BROADCASTER_H
559