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