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