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