]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/include/lldb/Utility/Broadcaster.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / include / lldb / Utility / Broadcaster.h
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:
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
70 private:
71   ConstString m_broadcaster_class;
72   uint32_t m_event_bits;
73 };
74
75 class BroadcasterManager
76     : public std::enable_shared_from_this<BroadcasterManager> {
77 public:
78   friend class Listener;
79
80 protected:
81   BroadcasterManager();
82
83 public:
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
108 private:
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
243 class Broadcaster {
244   friend class Listener;
245   friend class Event;
246
247 public:
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
426 protected:
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
546 private:
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