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