Broadcaster.h revision 360660
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(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  BroadcastEventSpec &operator=(const BroadcastEventSpec &rhs);
69
70private:
71  ConstString m_broadcaster_class;
72  uint32_t m_event_bits;
73};
74
75class BroadcasterManager
76    : public std::enable_shared_from_this<BroadcasterManager> {
77public:
78  friend class Listener;
79
80protected:
81  BroadcasterManager();
82
83public:
84  /// Listeners hold onto weak pointers to their broadcaster managers.  So they
85  /// must be made into shared pointers, which you do with
86  /// MakeBroadcasterManager.
87  static lldb::BroadcasterManagerSP MakeBroadcasterManager();
88
89  ~BroadcasterManager() = default;
90
91  uint32_t RegisterListenerForEvents(const lldb::ListenerSP &listener_sp,
92                                     const BroadcastEventSpec &event_spec);
93
94  bool UnregisterListenerForEvents(const lldb::ListenerSP &listener_sp,
95                                   const BroadcastEventSpec &event_spec);
96
97  lldb::ListenerSP
98  GetListenerForEventSpec(const BroadcastEventSpec &event_spec) const;
99
100  void SignUpListenersForBroadcaster(Broadcaster &broadcaster);
101
102  void RemoveListener(const lldb::ListenerSP &listener_sp);
103
104  void RemoveListener(Listener *listener);
105
106  void Clear();
107
108private:
109  typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key;
110  typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection;
111  typedef std::set<lldb::ListenerSP> listener_collection;
112  collection m_event_map;
113  listener_collection m_listeners;
114
115  mutable std::recursive_mutex m_manager_mutex;
116
117  // A couple of comparator classes for find_if:
118
119  class BroadcasterClassMatches {
120  public:
121    BroadcasterClassMatches(ConstString broadcaster_class)
122        : m_broadcaster_class(broadcaster_class) {}
123
124    ~BroadcasterClassMatches() = default;
125
126    bool operator()(const event_listener_key &input) const {
127      return (input.first.GetBroadcasterClass() == m_broadcaster_class);
128    }
129
130  private:
131    ConstString m_broadcaster_class;
132  };
133
134  class BroadcastEventSpecMatches {
135  public:
136    BroadcastEventSpecMatches(const BroadcastEventSpec &broadcaster_spec)
137        : m_broadcaster_spec(broadcaster_spec) {}
138
139    ~BroadcastEventSpecMatches() = default;
140
141    bool operator()(const event_listener_key &input) const {
142      return (input.first.IsContainedIn(m_broadcaster_spec));
143    }
144
145  private:
146    BroadcastEventSpec m_broadcaster_spec;
147  };
148
149  class ListenerMatchesAndSharedBits {
150  public:
151    explicit ListenerMatchesAndSharedBits(
152        const BroadcastEventSpec &broadcaster_spec,
153        const lldb::ListenerSP &listener_sp)
154        : m_broadcaster_spec(broadcaster_spec), m_listener_sp(listener_sp) {}
155
156    ~ListenerMatchesAndSharedBits() = default;
157
158    bool operator()(const event_listener_key &input) const {
159      return (input.first.GetBroadcasterClass() ==
160                  m_broadcaster_spec.GetBroadcasterClass() &&
161              (input.first.GetEventBits() &
162               m_broadcaster_spec.GetEventBits()) != 0 &&
163              input.second == m_listener_sp);
164    }
165
166  private:
167    BroadcastEventSpec m_broadcaster_spec;
168    const lldb::ListenerSP m_listener_sp;
169  };
170
171  class ListenerMatches {
172  public:
173    explicit ListenerMatches(const lldb::ListenerSP &in_listener_sp)
174        : m_listener_sp(in_listener_sp) {}
175
176    ~ListenerMatches() = default;
177
178    bool operator()(const event_listener_key &input) const {
179      if (input.second == m_listener_sp)
180        return true;
181
182      return false;
183    }
184
185  private:
186    const lldb::ListenerSP m_listener_sp;
187  };
188
189  class ListenerMatchesPointer {
190  public:
191    ListenerMatchesPointer(const Listener *in_listener)
192        : m_listener(in_listener) {}
193
194    ~ListenerMatchesPointer() = default;
195
196    bool operator()(const event_listener_key &input) const {
197      if (input.second.get() == m_listener)
198        return true;
199
200      return false;
201    }
202
203    bool operator()(const lldb::ListenerSP &input) const {
204      if (input.get() == m_listener)
205        return true;
206
207      return false;
208    }
209
210  private:
211    const Listener *m_listener;
212  };
213};
214
215/// \class Broadcaster Broadcaster.h "lldb/Utility/Broadcaster.h" An event
216/// broadcasting class.
217///
218/// The Broadcaster class is designed to be subclassed by objects that wish to
219/// vend events in a multi-threaded environment. Broadcaster objects can each
220/// vend 32 events. Each event is represented by a bit in a 32 bit value and
221/// these bits can be set:
222///     \see Broadcaster::SetEventBits(uint32_t)
223/// or cleared:
224///     \see Broadcaster::ResetEventBits(uint32_t)
225/// When an event gets set the Broadcaster object will notify the Listener
226/// object that is listening for the event (if there is one).
227///
228/// Subclasses should provide broadcast bit definitions for any events they
229/// vend, typically using an enumeration:
230///     \code
231///         class Foo : public Broadcaster
232///         {
233///         public:
234///         // Broadcaster event bits definitions.
235///         enum
236///         {
237///             eBroadcastBitOne   = (1 << 0),
238///             eBroadcastBitTwo   = (1 << 1),
239///             eBroadcastBitThree = (1 << 2),
240///             ...
241///         };
242///     \endcode
243class Broadcaster {
244  friend class Listener;
245  friend class Event;
246
247public:
248  /// Construct with a broadcaster with a name.
249  ///
250  /// \param[in] name
251  ///     A NULL terminated C string that contains the name of the
252  ///     broadcaster object.
253  Broadcaster(lldb::BroadcasterManagerSP manager_sp, const char *name);
254
255  /// Destructor.
256  ///
257  /// The destructor is virtual since this class gets subclassed.
258  virtual ~Broadcaster();
259
260  void CheckInWithManager();
261
262  /// Broadcast an event which has no associated data.
263  ///
264  /// \param[in] event_type
265  ///     The element from the enum defining this broadcaster's events
266  ///     that is being broadcast.
267  ///
268  /// \param[in] event_data
269  ///     User event data that will be owned by the lldb::Event that
270  ///     is created internally.
271  ///
272  /// \param[in] unique
273  ///     If true, then only add an event of this type if there isn't
274  ///     one already in the queue.
275  ///
276  void BroadcastEvent(lldb::EventSP &event_sp) {
277    m_broadcaster_sp->BroadcastEvent(event_sp);
278  }
279
280  void BroadcastEventIfUnique(lldb::EventSP &event_sp) {
281    m_broadcaster_sp->BroadcastEventIfUnique(event_sp);
282  }
283
284  void BroadcastEvent(uint32_t event_type,
285                      const lldb::EventDataSP &event_data_sp) {
286    m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp);
287  }
288
289  void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr) {
290    m_broadcaster_sp->BroadcastEvent(event_type, event_data);
291  }
292
293  void BroadcastEventIfUnique(uint32_t event_type,
294                              EventData *event_data = nullptr) {
295    m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data);
296  }
297
298  void Clear() { m_broadcaster_sp->Clear(); }
299
300  virtual void AddInitialEventsToListener(const lldb::ListenerSP &listener_sp,
301                                          uint32_t requested_events);
302
303  /// Listen for any events specified by \a event_mask.
304  ///
305  /// Only one listener can listen to each event bit in a given Broadcaster.
306  /// Once a listener has acquired an event bit, no other broadcaster will
307  /// have access to it until it is relinquished by the first listener that
308  /// gets it. The actual event bits that get acquired by \a listener may be
309  /// different from what is requested in \a event_mask, and to track this the
310  /// actual event bits that are acquired get returned.
311  ///
312  /// \param[in] listener
313  ///     The Listener object that wants to monitor the events that
314  ///     get broadcast by this object.
315  ///
316  /// \param[in] event_mask
317  ///     A bit mask that indicates which events the listener is
318  ///     asking to monitor.
319  ///
320  /// \return
321  ///     The actual event bits that were acquired by \a listener.
322  uint32_t AddListener(const lldb::ListenerSP &listener_sp,
323                       uint32_t event_mask) {
324    return m_broadcaster_sp->AddListener(listener_sp, event_mask);
325  }
326
327  /// Get the NULL terminated C string name of this Broadcaster object.
328  ///
329  /// \return
330  ///     The NULL terminated C string name of this Broadcaster.
331  ConstString GetBroadcasterName() { return m_broadcaster_name; }
332
333  /// Get the event name(s) for one or more event bits.
334  ///
335  /// \param[in] event_mask
336  ///     A bit mask that indicates which events to get names for.
337  ///
338  /// \return
339  ///     The NULL terminated C string name of this Broadcaster.
340  bool GetEventNames(Stream &s, const uint32_t event_mask,
341                     bool prefix_with_broadcaster_name) const {
342    return m_broadcaster_sp->GetEventNames(s, event_mask,
343                                           prefix_with_broadcaster_name);
344  }
345
346  /// Set the name for an event bit.
347  ///
348  /// \param[in] event_mask
349  ///     A bit mask that indicates which events the listener is
350  ///     asking to monitor.
351  ///
352  /// \return
353  ///     The NULL terminated C string name of this Broadcaster.
354  void SetEventName(uint32_t event_mask, const char *name) {
355    m_broadcaster_sp->SetEventName(event_mask, name);
356  }
357
358  const char *GetEventName(uint32_t event_mask) const {
359    return m_broadcaster_sp->GetEventName(event_mask);
360  }
361
362  bool EventTypeHasListeners(uint32_t event_type) {
363    return m_broadcaster_sp->EventTypeHasListeners(event_type);
364  }
365
366  /// Removes a Listener from this broadcasters list and frees the event bits
367  /// specified by \a event_mask that were previously acquired by \a listener
368  /// (assuming \a listener was listening to this object) for other listener
369  /// objects to use.
370  ///
371  /// \param[in] listener
372  ///     A Listener object that previously called AddListener.
373  ///
374  /// \param[in] event_mask
375  ///     The event bits \a listener wishes to relinquish.
376  ///
377  /// \return
378  ///     \b True if the listener was listening to this broadcaster
379  ///     and was removed, \b false otherwise.
380  ///
381  /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
382  bool RemoveListener(const lldb::ListenerSP &listener_sp,
383                      uint32_t event_mask = UINT32_MAX) {
384    return m_broadcaster_sp->RemoveListener(listener_sp, event_mask);
385  }
386
387  /// Provides a simple mechanism to temporarily redirect events from
388  /// broadcaster.  When you call this function passing in a listener and
389  /// event type mask, all events from the broadcaster matching the mask will
390  /// now go to the hijacking listener. Only one hijack can occur at a time.
391  /// If we need more than this we will have to implement a Listener stack.
392  ///
393  /// \param[in] listener
394  ///     A Listener object.  You do not need to call StartListeningForEvents
395  ///     for this broadcaster (that would fail anyway since the event bits
396  ///     would most likely be taken by the listener(s) you are usurping.
397  ///
398  /// \param[in] event_mask
399  ///     The event bits \a listener wishes to hijack.
400  ///
401  /// \return
402  ///     \b True if the event mask could be hijacked, \b false otherwise.
403  ///
404  /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
405  bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
406                         uint32_t event_mask = UINT32_MAX) {
407    return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask);
408  }
409
410  bool IsHijackedForEvent(uint32_t event_mask) {
411    return m_broadcaster_sp->IsHijackedForEvent(event_mask);
412  }
413
414  /// Restore the state of the Broadcaster from a previous hijack attempt.
415  void RestoreBroadcaster() { m_broadcaster_sp->RestoreBroadcaster(); }
416
417  /// This needs to be filled in if you are going to register the broadcaster
418  /// with the broadcaster manager and do broadcaster class matching.
419  /// FIXME: Probably should make a ManagedBroadcaster subclass with all the
420  /// bits needed to work with the BroadcasterManager, so that it is clearer
421  /// how to add one.
422  virtual ConstString &GetBroadcasterClass() const;
423
424  lldb::BroadcasterManagerSP GetManager();
425
426protected:
427  /// BroadcasterImpl contains the actual Broadcaster implementation.  The
428  /// Broadcaster makes a BroadcasterImpl which lives as long as it does.  The
429  /// Listeners & the Events hold a weak pointer to the BroadcasterImpl, so
430  /// that they can survive if a Broadcaster they were listening to is
431  /// destroyed w/o their being able to unregister from it (which can happen if
432  /// the Broadcasters & Listeners are being destroyed on separate threads
433  /// simultaneously. The Broadcaster itself can't be shared out as a weak
434  /// pointer, because some things that are broadcasters (e.g. the Target and
435  /// the Process) are shared in their own right.
436  ///
437  /// For the most part, the Broadcaster functions dispatch to the
438  /// BroadcasterImpl, and are documented in the public Broadcaster API above.
439  class BroadcasterImpl {
440    friend class Listener;
441    friend class Broadcaster;
442
443  public:
444    BroadcasterImpl(Broadcaster &broadcaster);
445
446    ~BroadcasterImpl() = default;
447
448    void BroadcastEvent(lldb::EventSP &event_sp);
449
450    void BroadcastEventIfUnique(lldb::EventSP &event_sp);
451
452    void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr);
453
454    void BroadcastEvent(uint32_t event_type,
455                        const lldb::EventDataSP &event_data_sp);
456
457    void BroadcastEventIfUnique(uint32_t event_type,
458                                EventData *event_data = nullptr);
459
460    void Clear();
461
462    uint32_t AddListener(const lldb::ListenerSP &listener_sp,
463                         uint32_t event_mask);
464
465    const char *GetBroadcasterName() const {
466      return m_broadcaster.GetBroadcasterName().AsCString();
467    }
468
469    Broadcaster *GetBroadcaster();
470
471    bool GetEventNames(Stream &s, const uint32_t event_mask,
472                       bool prefix_with_broadcaster_name) const;
473
474    void SetEventName(uint32_t event_mask, const char *name) {
475      m_event_names[event_mask] = name;
476    }
477
478    const char *GetEventName(uint32_t event_mask) const {
479      const auto pos = m_event_names.find(event_mask);
480      if (pos != m_event_names.end())
481        return pos->second.c_str();
482      return nullptr;
483    }
484
485    bool EventTypeHasListeners(uint32_t event_type);
486
487    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