xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Utility/Broadcaster.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
27 namespace lldb_private {
28 class Broadcaster;
29 class EventData;
30 class Listener;
31 class Stream;
32 } // namespace lldb_private
33 
34 namespace 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
40 class BroadcastEventSpec {
41 public:
BroadcastEventSpec(llvm::StringRef broadcaster_class,uint32_t event_bits)42   BroadcastEventSpec(llvm::StringRef broadcaster_class, uint32_t event_bits)
43       : m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {}
44 
45   ~BroadcastEventSpec() = default;
46 
GetBroadcasterClass()47   const std::string &GetBroadcasterClass() const { return m_broadcaster_class; }
48 
GetEventBits()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.
IsContainedIn(const BroadcastEventSpec & 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 
69 private:
70   std::string m_broadcaster_class;
71   uint32_t m_event_bits;
72 };
73 
74 class BroadcasterManager
75     : public std::enable_shared_from_this<BroadcasterManager> {
76 public:
77   friend class Listener;
78 
79 protected:
80   BroadcasterManager();
81 
82 public:
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   lldb::ListenerSP
91   GetListenerForEventSpec(const BroadcastEventSpec &event_spec) const;
92 
93   void SignUpListenersForBroadcaster(Broadcaster &broadcaster);
94 
95   void RemoveListener(const lldb::ListenerSP &listener_sp);
96 
97   void RemoveListener(Listener *listener);
98 
99   void Clear();
100 
101 private:
102   uint32_t
103   RegisterListenerForEventsNoLock(const lldb::ListenerSP &listener_sp,
104                                   const BroadcastEventSpec &event_spec);
105 
106   bool UnregisterListenerForEventsNoLock(const lldb::ListenerSP &listener_sp,
107                                          const BroadcastEventSpec &event_spec);
108 
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::mutex m_manager_mutex;
116 };
117 
118 /// \class Broadcaster Broadcaster.h "lldb/Utility/Broadcaster.h" An event
119 /// broadcasting class.
120 ///
121 /// The Broadcaster class is designed to be subclassed by objects that wish to
122 /// vend events in a multi-threaded environment. Broadcaster objects can each
123 /// vend 32 events. Each event is represented by a bit in a 32 bit value and
124 /// these bits can be set:
125 ///     \see Broadcaster::SetEventBits(uint32_t)
126 /// or cleared:
127 ///     \see Broadcaster::ResetEventBits(uint32_t)
128 /// When an event gets set the Broadcaster object will notify the Listener
129 /// object that is listening for the event (if there is one).
130 ///
131 /// Subclasses should provide broadcast bit definitions for any events they
132 /// vend, typically using an enumeration:
133 ///     \code
134 ///         class Foo : public Broadcaster
135 ///         {
136 ///         public:
137 ///         // Broadcaster event bits definitions.
138 ///         enum
139 ///         {
140 ///             eBroadcastBitOne   = (1 << 0),
141 ///             eBroadcastBitTwo   = (1 << 1),
142 ///             eBroadcastBitThree = (1 << 2),
143 ///             ...
144 ///         };
145 ///     \endcode
146 class Broadcaster {
147   friend class Listener;
148   friend class Event;
149 
150 public:
151   /// Construct with a broadcaster with a name.
152   ///
153   /// \param[in] manager_sp
154   ///   A shared pointer to the BroadcasterManager that will manage this
155   ///   broadcaster.
156   /// \param[in] name
157   ///   A std::string of the name that this broadcaster will have.
158   Broadcaster(lldb::BroadcasterManagerSP manager_sp, std::string name);
159 
160   /// Destructor.
161   ///
162   /// The destructor is virtual since this class gets subclassed.
163   virtual ~Broadcaster();
164 
165   void CheckInWithManager();
166 
167   /// Broadcast an event which has no associated data.
BroadcastEvent(lldb::EventSP & event_sp)168   void BroadcastEvent(lldb::EventSP &event_sp) {
169     m_broadcaster_sp->BroadcastEvent(event_sp);
170   }
171 
BroadcastEventIfUnique(lldb::EventSP & event_sp)172   void BroadcastEventIfUnique(lldb::EventSP &event_sp) {
173     m_broadcaster_sp->BroadcastEventIfUnique(event_sp);
174   }
175 
BroadcastEvent(uint32_t event_type,const lldb::EventDataSP & event_data_sp)176   void BroadcastEvent(uint32_t event_type,
177                       const lldb::EventDataSP &event_data_sp) {
178     m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp);
179   }
180 
BroadcastEvent(uint32_t event_type)181   void BroadcastEvent(uint32_t event_type) {
182     m_broadcaster_sp->BroadcastEvent(event_type);
183   }
184 
BroadcastEventIfUnique(uint32_t event_type)185   void BroadcastEventIfUnique(uint32_t event_type) {
186     m_broadcaster_sp->BroadcastEventIfUnique(event_type);
187   }
188 
Clear()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.
AddListener(const lldb::ListenerSP & listener_sp,uint32_t event_mask)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.
GetBroadcasterName()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.
GetEventNames(Stream & s,const uint32_t event_mask,bool prefix_with_broadcaster_name)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.
SetEventName(uint32_t event_mask,const char * name)243   void SetEventName(uint32_t event_mask, const char *name) {
244     m_broadcaster_sp->SetEventName(event_mask, name);
245   }
246 
GetEventName(uint32_t event_mask)247   const char *GetEventName(uint32_t event_mask) const {
248     return m_broadcaster_sp->GetEventName(event_mask);
249   }
250 
EventTypeHasListeners(uint32_t event_type)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 
IsHijackedForEvent(uint32_t event_mask)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.
RestoreBroadcaster()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 llvm::StringRef GetBroadcasterClass() const;
312 
313   lldb::BroadcasterManagerSP GetManager();
314 
SetPrimaryListener(lldb::ListenerSP listener_sp)315   void SetPrimaryListener(lldb::ListenerSP listener_sp) {
316     m_broadcaster_sp->SetPrimaryListener(listener_sp);
317   }
318 
GetPrimaryListener()319   lldb::ListenerSP GetPrimaryListener() {
320     return m_broadcaster_sp->m_primary_listener_sp;
321   }
322 
323 protected:
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 
356     void Clear();
357 
358     uint32_t AddListener(const lldb::ListenerSP &listener_sp,
359                          uint32_t event_mask);
360 
GetBroadcasterName()361     const std::string &GetBroadcasterName() const {
362       return m_broadcaster.GetBroadcasterName();
363     }
364 
365     Broadcaster *GetBroadcaster();
366 
367     bool GetEventNames(Stream &s, const uint32_t event_mask,
368                        bool prefix_with_broadcaster_name) const;
369 
SetEventName(uint32_t event_mask,const char * name)370     void SetEventName(uint32_t event_mask, const char *name) {
371       m_event_names[event_mask] = name;
372     }
373 
GetEventName(uint32_t event_mask)374     const char *GetEventName(uint32_t event_mask) const {
375       const auto pos = m_event_names.find(event_mask);
376       if (pos != m_event_names.end())
377         return pos->second.c_str();
378       return nullptr;
379     }
380 
381     bool EventTypeHasListeners(uint32_t event_type);
382 
383     void SetPrimaryListener(lldb::ListenerSP listener_sp);
384 
385     bool RemoveListener(lldb_private::Listener *listener,
386                         uint32_t event_mask = UINT32_MAX);
387 
388     bool RemoveListener(const lldb::ListenerSP &listener_sp,
389                         uint32_t event_mask = UINT32_MAX);
390 
391     bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
392                            uint32_t event_mask = UINT32_MAX);
393 
394     bool IsHijackedForEvent(uint32_t event_mask);
395 
396     void RestoreBroadcaster();
397 
398   protected:
399     void PrivateBroadcastEvent(lldb::EventSP &event_sp, bool unique);
400 
401     const char *GetHijackingListenerName();
402 
403     typedef llvm::SmallVector<std::pair<lldb::ListenerWP, uint32_t>, 4>
404         collection;
405     typedef std::map<uint32_t, std::string> event_names_map;
406 
407     llvm::SmallVector<std::pair<lldb::ListenerSP, uint32_t &>, 4>
408     GetListeners(uint32_t event_mask = UINT32_MAX, bool include_primary = true);
409 
410     bool HasListeners(uint32_t event_mask);
411 
412     /// The broadcaster that this implements.
413     Broadcaster &m_broadcaster;
414 
415     /// Optionally define event names for readability and logging for each
416     /// event bit.
417     event_names_map m_event_names;
418 
419     /// A Broadcaster can have zero, one or many listeners.  A Broadcaster with
420     /// zero listeners is a no-op, with one Listener is trivial.
421     /// In most cases of multiple Listeners,the Broadcaster treats all its
422     /// Listeners as equal, sending each event to all of the Listeners in no
423     /// guaranteed order.
424     /// However, some Broadcasters - in particular the Process broadcaster, can
425     /// designate one Listener to be the "Primary Listener".  In the case of
426     /// the Process Broadcaster, the Listener passed to the Process constructor
427     /// will be the Primary Listener.
428     /// If the broadcaster has a Primary Listener, then the event gets
429     /// sent first to the Primary Listener, and then when the Primary Listener
430     /// pulls the event and the the event's DoOnRemoval finishes running,
431     /// the event is forwarded to all the other Listeners.
432     /// The other wrinkle is that a Broadcaster may be serving a Hijack
433     /// Listener.  If the Hijack Listener is present, events are only sent to
434     /// the Hijack Listener.  We use that, for instance, to absorb all the
435     /// events generated by running an expression so that they don't show up to
436     /// the driver or UI as starts and stops.
437     /// If a Broadcaster has both a Primary and a Hijack Listener, the top-most
438     /// Hijack Listener is treated as the current Primary Listener.
439 
440     /// A list of Listener / event_mask pairs that are listening to this
441     /// broadcaster.
442     collection m_listeners;
443 
444     /// A mutex that protects \a m_listeners.
445     std::mutex m_listeners_mutex;
446 
447     /// See the discussion of Broadcasters and Listeners above.
448     lldb::ListenerSP m_primary_listener_sp;
449     // The primary listener listens to all bits:
450     uint32_t m_primary_listener_mask = UINT32_MAX;
451 
452     /// A simple mechanism to intercept events from a broadcaster
453     std::vector<lldb::ListenerSP> m_hijacking_listeners;
454 
455     /// At some point we may want to have a stack or Listener collections, but
456     /// for now this is just for private hijacking.
457     std::vector<uint32_t> m_hijacking_masks;
458 
459   private:
460     BroadcasterImpl(const BroadcasterImpl &) = delete;
461     const BroadcasterImpl &operator=(const BroadcasterImpl &) = delete;
462   };
463 
464   typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP;
465   typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP;
466 
GetBroadcasterImpl()467   BroadcasterImplSP GetBroadcasterImpl() { return m_broadcaster_sp; }
468 
GetHijackingListenerName()469   const char *GetHijackingListenerName() {
470     return m_broadcaster_sp->GetHijackingListenerName();
471   }
472 
473 private:
474   BroadcasterImplSP m_broadcaster_sp;
475   lldb::BroadcasterManagerSP m_manager_sp;
476 
477   /// The name of this broadcaster object.
478   const std::string m_broadcaster_name;
479 
480   Broadcaster(const Broadcaster &) = delete;
481   const Broadcaster &operator=(const Broadcaster &) = delete;
482 };
483 
484 } // namespace lldb_private
485 
486 #endif // LLDB_UTILITY_BROADCASTER_H
487