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