1//===-- Broadcaster.h -------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_UTILITY_BROADCASTER_H
10#define LLDB_UTILITY_BROADCASTER_H
11
12#include "lldb/Utility/ConstString.h"
13#include "lldb/lldb-defines.h"
14#include "lldb/lldb-forward.h"
15
16#include "llvm/ADT/SmallVector.h"
17
18#include <cstdint>
19#include <map>
20#include <memory>
21#include <mutex>
22#include <set>
23#include <string>
24#include <utility>
25#include <vector>
26
27namespace lldb_private {
28class Broadcaster;
29class EventData;
30class Listener;
31class Stream;
32} // namespace lldb_private
33
34namespace lldb_private {
35
36/// lldb::BroadcastEventSpec
37///
38/// This class is used to specify a kind of event to register for.  The
39/// Debugger maintains a list of BroadcastEventSpec's and when it is made
40class BroadcastEventSpec {
41public:
42  BroadcastEventSpec(const ConstString &broadcaster_class, uint32_t event_bits)
43      : m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {}
44
45  ~BroadcastEventSpec() = default;
46
47  ConstString GetBroadcasterClass() const { return m_broadcaster_class; }
48
49  uint32_t GetEventBits() const { return m_event_bits; }
50
51  /// Tell whether this BroadcastEventSpec is contained in in_spec. That is:
52  /// (a) the two spec's share the same broadcaster class (b) the event bits of
53  /// this spec are wholly contained in those of in_spec.
54  bool IsContainedIn(const BroadcastEventSpec &in_spec) const {
55    if (m_broadcaster_class != in_spec.GetBroadcasterClass())
56      return false;
57    uint32_t in_bits = in_spec.GetEventBits();
58    if (in_bits == m_event_bits)
59      return true;
60
61    if ((m_event_bits & in_bits) != 0 && (m_event_bits & ~in_bits) == 0)
62      return true;
63
64    return false;
65  }
66
67  bool operator<(const BroadcastEventSpec &rhs) const;
68
69private:
70  ConstString m_broadcaster_class;
71  uint32_t m_event_bits;
72};
73
74class BroadcasterManager
75    : public std::enable_shared_from_this<BroadcasterManager> {
76public:
77  friend class Listener;
78
79protected:
80  BroadcasterManager();
81
82public:
83  /// Listeners hold onto weak pointers to their broadcaster managers.  So they
84  /// must be made into shared pointers, which you do with
85  /// MakeBroadcasterManager.
86  static lldb::BroadcasterManagerSP MakeBroadcasterManager();
87
88  ~BroadcasterManager() = default;
89
90  uint32_t RegisterListenerForEvents(const lldb::ListenerSP &listener_sp,
91                                     const BroadcastEventSpec &event_spec);
92
93  bool UnregisterListenerForEvents(const lldb::ListenerSP &listener_sp,
94                                   const BroadcastEventSpec &event_spec);
95
96  lldb::ListenerSP
97  GetListenerForEventSpec(const BroadcastEventSpec &event_spec) const;
98
99  void SignUpListenersForBroadcaster(Broadcaster &broadcaster);
100
101  void RemoveListener(const lldb::ListenerSP &listener_sp);
102
103  void RemoveListener(Listener *listener);
104
105  void Clear();
106
107private:
108  typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key;
109  typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection;
110  typedef std::set<lldb::ListenerSP> listener_collection;
111  collection m_event_map;
112  listener_collection m_listeners;
113
114  mutable std::recursive_mutex m_manager_mutex;
115};
116
117/// \class Broadcaster Broadcaster.h "lldb/Utility/Broadcaster.h" An event
118/// broadcasting class.
119///
120/// The Broadcaster class is designed to be subclassed by objects that wish to
121/// vend events in a multi-threaded environment. Broadcaster objects can each
122/// vend 32 events. Each event is represented by a bit in a 32 bit value and
123/// these bits can be set:
124///     \see Broadcaster::SetEventBits(uint32_t)
125/// or cleared:
126///     \see Broadcaster::ResetEventBits(uint32_t)
127/// When an event gets set the Broadcaster object will notify the Listener
128/// object that is listening for the event (if there is one).
129///
130/// Subclasses should provide broadcast bit definitions for any events they
131/// vend, typically using an enumeration:
132///     \code
133///         class Foo : public Broadcaster
134///         {
135///         public:
136///         // Broadcaster event bits definitions.
137///         enum
138///         {
139///             eBroadcastBitOne   = (1 << 0),
140///             eBroadcastBitTwo   = (1 << 1),
141///             eBroadcastBitThree = (1 << 2),
142///             ...
143///         };
144///     \endcode
145class Broadcaster {
146  friend class Listener;
147  friend class Event;
148
149public:
150  /// Construct with a broadcaster with a name.
151  ///
152  /// \param[in] manager_sp
153  ///   A shared pointer to the BroadcasterManager that will manage this
154  ///   broadcaster.
155  /// \param[in] name
156  ///   A std::string of the name that this broadcaster will have.
157  Broadcaster(lldb::BroadcasterManagerSP manager_sp, std::string name);
158
159  /// Destructor.
160  ///
161  /// The destructor is virtual since this class gets subclassed.
162  virtual ~Broadcaster();
163
164  void CheckInWithManager();
165
166  /// Broadcast an event which has no associated data.
167  void BroadcastEvent(lldb::EventSP &event_sp) {
168    m_broadcaster_sp->BroadcastEvent(event_sp);
169  }
170
171  void BroadcastEventIfUnique(lldb::EventSP &event_sp) {
172    m_broadcaster_sp->BroadcastEventIfUnique(event_sp);
173  }
174
175  void BroadcastEvent(uint32_t event_type,
176                      const lldb::EventDataSP &event_data_sp) {
177    m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp);
178  }
179
180  void BroadcastEvent(uint32_t event_type) {
181    m_broadcaster_sp->BroadcastEvent(event_type);
182  }
183
184  void BroadcastEventIfUnique(uint32_t event_type,
185                              EventData *event_data = nullptr) {
186    m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data);
187  }
188
189  void Clear() { m_broadcaster_sp->Clear(); }
190
191  virtual void AddInitialEventsToListener(const lldb::ListenerSP &listener_sp,
192                                          uint32_t requested_events);
193
194  /// Listen for any events specified by \a event_mask.
195  ///
196  /// Only one listener can listen to each event bit in a given Broadcaster.
197  /// Once a listener has acquired an event bit, no other broadcaster will
198  /// have access to it until it is relinquished by the first listener that
199  /// gets it. The actual event bits that get acquired by \a listener may be
200  /// different from what is requested in \a event_mask, and to track this the
201  /// actual event bits that are acquired get returned.
202  ///
203  /// \param[in] listener_sp
204  ///     The Listener object that wants to monitor the events that
205  ///     get broadcast by this object.
206  ///
207  /// \param[in] event_mask
208  ///     A bit mask that indicates which events the listener is
209  ///     asking to monitor.
210  ///
211  /// \return
212  ///     The actual event bits that were acquired by \a listener.
213  uint32_t AddListener(const lldb::ListenerSP &listener_sp,
214                       uint32_t event_mask) {
215    return m_broadcaster_sp->AddListener(listener_sp, event_mask);
216  }
217
218  /// Get this broadcaster's name.
219  ///
220  /// \return
221  ///     A reference to a constant std::string containing the name of the
222  ///     broadcaster.
223  const std::string &GetBroadcasterName() { return m_broadcaster_name; }
224
225  /// Get the event name(s) for one or more event bits.
226  ///
227  /// \param[in] event_mask
228  ///     A bit mask that indicates which events to get names for.
229  ///
230  /// \return
231  ///     The NULL terminated C string name of this Broadcaster.
232  bool GetEventNames(Stream &s, const uint32_t event_mask,
233                     bool prefix_with_broadcaster_name) const {
234    return m_broadcaster_sp->GetEventNames(s, event_mask,
235                                           prefix_with_broadcaster_name);
236  }
237
238  /// Set the name for an event bit.
239  ///
240  /// \param[in] event_mask
241  ///     A bit mask that indicates which events the listener is
242  ///     asking to monitor.
243  void SetEventName(uint32_t event_mask, const char *name) {
244    m_broadcaster_sp->SetEventName(event_mask, name);
245  }
246
247  const char *GetEventName(uint32_t event_mask) const {
248    return m_broadcaster_sp->GetEventName(event_mask);
249  }
250
251  bool EventTypeHasListeners(uint32_t event_type) {
252    return m_broadcaster_sp->EventTypeHasListeners(event_type);
253  }
254
255  /// Removes a Listener from this broadcasters list and frees the event bits
256  /// specified by \a event_mask that were previously acquired by \a listener
257  /// (assuming \a listener was listening to this object) for other listener
258  /// objects to use.
259  ///
260  /// \param[in] listener_sp
261  ///     A Listener object that previously called AddListener.
262  ///
263  /// \param[in] event_mask
264  ///     The event bits \a listener wishes to relinquish.
265  ///
266  /// \return
267  ///     \b True if the listener was listening to this broadcaster
268  ///     and was removed, \b false otherwise.
269  ///
270  /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
271  bool RemoveListener(const lldb::ListenerSP &listener_sp,
272                      uint32_t event_mask = UINT32_MAX) {
273    return m_broadcaster_sp->RemoveListener(listener_sp, event_mask);
274  }
275
276  /// Provides a simple mechanism to temporarily redirect events from
277  /// broadcaster.  When you call this function passing in a listener and
278  /// event type mask, all events from the broadcaster matching the mask will
279  /// now go to the hijacking listener. Only one hijack can occur at a time.
280  /// If we need more than this we will have to implement a Listener stack.
281  ///
282  /// \param[in] listener_sp
283  ///     A Listener object.  You do not need to call StartListeningForEvents
284  ///     for this broadcaster (that would fail anyway since the event bits
285  ///     would most likely be taken by the listener(s) you are usurping.
286  ///
287  /// \param[in] event_mask
288  ///     The event bits \a listener wishes to hijack.
289  ///
290  /// \return
291  ///     \b True if the event mask could be hijacked, \b false otherwise.
292  ///
293  /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
294  bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
295                         uint32_t event_mask = UINT32_MAX) {
296    return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask);
297  }
298
299  bool IsHijackedForEvent(uint32_t event_mask) {
300    return m_broadcaster_sp->IsHijackedForEvent(event_mask);
301  }
302
303  /// Restore the state of the Broadcaster from a previous hijack attempt.
304  void RestoreBroadcaster() { m_broadcaster_sp->RestoreBroadcaster(); }
305
306  /// This needs to be filled in if you are going to register the broadcaster
307  /// with the broadcaster manager and do broadcaster class matching.
308  /// FIXME: Probably should make a ManagedBroadcaster subclass with all the
309  /// bits needed to work with the BroadcasterManager, so that it is clearer
310  /// how to add one.
311  virtual ConstString &GetBroadcasterClass() const;
312
313  lldb::BroadcasterManagerSP GetManager();
314
315  void SetPrimaryListener(lldb::ListenerSP listener_sp) {
316    m_broadcaster_sp->SetPrimaryListener(listener_sp);
317  }
318
319  lldb::ListenerSP GetPrimaryListener() {
320    return m_broadcaster_sp->m_primary_listener_sp;
321  }
322
323protected:
324  /// BroadcasterImpl contains the actual Broadcaster implementation.  The
325  /// Broadcaster makes a BroadcasterImpl which lives as long as it does.  The
326  /// Listeners & the Events hold a weak pointer to the BroadcasterImpl, so
327  /// that they can survive if a Broadcaster they were listening to is
328  /// destroyed w/o their being able to unregister from it (which can happen if
329  /// the Broadcasters & Listeners are being destroyed on separate threads
330  /// simultaneously. The Broadcaster itself can't be shared out as a weak
331  /// pointer, because some things that are broadcasters (e.g. the Target and
332  /// the Process) are shared in their own right.
333  ///
334  /// For the most part, the Broadcaster functions dispatch to the
335  /// BroadcasterImpl, and are documented in the public Broadcaster API above.
336  class BroadcasterImpl {
337    friend class Listener;
338    friend class Broadcaster;
339
340  public:
341    BroadcasterImpl(Broadcaster &broadcaster);
342
343    ~BroadcasterImpl() = default;
344
345    void BroadcastEvent(lldb::EventSP &event_sp);
346
347    void BroadcastEventIfUnique(lldb::EventSP &event_sp);
348
349    void BroadcastEvent(uint32_t event_type);
350
351    void BroadcastEvent(uint32_t event_type,
352                        const lldb::EventDataSP &event_data_sp);
353
354    void BroadcastEventIfUnique(uint32_t event_type,
355                                EventData *event_data = nullptr);
356
357    void Clear();
358
359    uint32_t AddListener(const lldb::ListenerSP &listener_sp,
360                         uint32_t event_mask);
361
362    const std::string &GetBroadcasterName() const {
363      return m_broadcaster.GetBroadcasterName();
364    }
365
366    Broadcaster *GetBroadcaster();
367
368    bool GetEventNames(Stream &s, const uint32_t event_mask,
369                       bool prefix_with_broadcaster_name) const;
370
371    void SetEventName(uint32_t event_mask, const char *name) {
372      m_event_names[event_mask] = name;
373    }
374
375    const char *GetEventName(uint32_t event_mask) const {
376      const auto pos = m_event_names.find(event_mask);
377      if (pos != m_event_names.end())
378        return pos->second.c_str();
379      return nullptr;
380    }
381
382    bool EventTypeHasListeners(uint32_t event_type);
383
384    void SetPrimaryListener(lldb::ListenerSP listener_sp);
385
386    bool RemoveListener(lldb_private::Listener *listener,
387                        uint32_t event_mask = UINT32_MAX);
388
389    bool RemoveListener(const lldb::ListenerSP &listener_sp,
390                        uint32_t event_mask = UINT32_MAX);
391
392    bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
393                           uint32_t event_mask = UINT32_MAX);
394
395    bool IsHijackedForEvent(uint32_t event_mask);
396
397    void RestoreBroadcaster();
398
399  protected:
400    void PrivateBroadcastEvent(lldb::EventSP &event_sp, bool unique);
401
402    const char *GetHijackingListenerName();
403
404    typedef llvm::SmallVector<std::pair<lldb::ListenerWP, uint32_t>, 4>
405        collection;
406    typedef std::map<uint32_t, std::string> event_names_map;
407
408    llvm::SmallVector<std::pair<lldb::ListenerSP, uint32_t &>, 4>
409    GetListeners(uint32_t event_mask = UINT32_MAX, bool include_primary = true);
410
411    bool HasListeners(uint32_t event_mask);
412
413    /// The broadcaster that this implements.
414    Broadcaster &m_broadcaster;
415
416    /// Optionally define event names for readability and logging for each
417    /// event bit.
418    event_names_map m_event_names;
419
420    /// A Broadcaster can have zero, one or many listeners.  A Broadcaster with
421    /// zero listeners is a no-op, with one Listener is trivial.
422    /// In most cases of multiple Listeners,the Broadcaster treats all its
423    /// Listeners as equal, sending each event to all of the Listeners in no
424    /// guaranteed order.
425    /// However, some Broadcasters - in particular the Process broadcaster, can
426    /// designate one Listener to be the "Primary Listener".  In the case of
427    /// the Process Broadcaster, the Listener passed to the Process constructor
428    /// will be the Primary Listener.
429    /// If the broadcaster has a Primary Listener, then the event gets
430    /// sent first to the Primary Listener, and then when the Primary Listener
431    /// pulls the event and the the event's DoOnRemoval finishes running,
432    /// the event is forwarded to all the other Listeners.
433    /// The other wrinkle is that a Broadcaster may be serving a Hijack
434    /// Listener.  If the Hijack Listener is present, events are only sent to
435    /// the Hijack Listener.  We use that, for instance, to absorb all the
436    /// events generated by running an expression so that they don't show up to
437    /// the driver or UI as starts and stops.
438    /// If a Broadcaster has both a Primary and a Hijack Listener, the top-most
439    /// Hijack Listener is treated as the current Primary Listener.
440
441    /// A list of Listener / event_mask pairs that are listening to this
442    /// broadcaster.
443    collection m_listeners;
444
445    /// A mutex that protects \a m_listeners.
446    std::recursive_mutex m_listeners_mutex;
447
448    /// See the discussion of Broadcasters and Listeners above.
449    lldb::ListenerSP m_primary_listener_sp;
450    // The primary listener listens to all bits:
451    uint32_t m_primary_listener_mask = UINT32_MAX;
452
453    /// A simple mechanism to intercept events from a broadcaster
454    std::vector<lldb::ListenerSP> m_hijacking_listeners;
455
456    /// At some point we may want to have a stack or Listener collections, but
457    /// for now this is just for private hijacking.
458    std::vector<uint32_t> m_hijacking_masks;
459
460  private:
461    BroadcasterImpl(const BroadcasterImpl &) = delete;
462    const BroadcasterImpl &operator=(const BroadcasterImpl &) = delete;
463  };
464
465  typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP;
466  typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP;
467
468  BroadcasterImplSP GetBroadcasterImpl() { return m_broadcaster_sp; }
469
470  const char *GetHijackingListenerName() {
471    return m_broadcaster_sp->GetHijackingListenerName();
472  }
473
474private:
475  BroadcasterImplSP m_broadcaster_sp;
476  lldb::BroadcasterManagerSP m_manager_sp;
477
478  /// The name of this broadcaster object.
479  const std::string m_broadcaster_name;
480
481  Broadcaster(const Broadcaster &) = delete;
482  const Broadcaster &operator=(const Broadcaster &) = delete;
483};
484
485} // namespace lldb_private
486
487#endif // LLDB_UTILITY_BROADCASTER_H
488