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