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 <map>
16 #include <string>
17 #include <vector>
18 
19 // Other libraries and framework includes
20 // Project includes
21 #include "lldb/lldb-private.h"
22 //#include "lldb/Core/Flags.h"
23 #include "lldb/Core/ConstString.h"
24 #include "lldb/Core/Listener.h"
25 
26 namespace lldb_private {
27 
28 //----------------------------------------------------------------------
29 // lldb::BroadcastEventSpec
30 //
31 // This class is used to specify a kind of event to register for.  The Debugger
32 // maintains a list of BroadcastEventSpec's and when it is made
33 //----------------------------------------------------------------------
34 class BroadcastEventSpec
35 {
36 public:
BroadcastEventSpec(const ConstString & broadcaster_class,uint32_t event_bits)37     BroadcastEventSpec (const ConstString &broadcaster_class, uint32_t event_bits) :
38         m_broadcaster_class (broadcaster_class),
39         m_event_bits (event_bits)
40     {
41     }
42 
43     BroadcastEventSpec (const BroadcastEventSpec &rhs);
44 
~BroadcastEventSpec()45     ~BroadcastEventSpec() {}
46 
GetBroadcasterClass()47     const ConstString &GetBroadcasterClass() const
48     {
49         return m_broadcaster_class;
50     }
51 
GetEventBits()52     uint32_t GetEventBits () const
53     {
54         return m_event_bits;
55     }
56 
57     // Tell whether this BroadcastEventSpec is contained in in_spec.
58     // That is:
59     // (a) the two spec's share the same broadcaster class
60     // (b) the event bits of this spec are wholly contained in those of in_spec.
IsContainedIn(BroadcastEventSpec in_spec)61     bool IsContainedIn (BroadcastEventSpec in_spec) const
62     {
63         if (m_broadcaster_class != in_spec.GetBroadcasterClass())
64             return false;
65         uint32_t in_bits = in_spec.GetEventBits();
66         if (in_bits == m_event_bits)
67             return true;
68         else
69         {
70             if ((m_event_bits & in_bits) != 0
71                 && (m_event_bits & ~in_bits) == 0)
72                     return true;
73         }
74         return false;
75     }
76 
77     bool operator< (const BroadcastEventSpec &rhs) const;
78     const BroadcastEventSpec &operator= (const BroadcastEventSpec &rhs);
79 
80 private:
81     ConstString m_broadcaster_class;
82     uint32_t m_event_bits;
83 };
84 
85 class BroadcasterManager
86 {
87 public:
88     friend class Listener;
89 
90     BroadcasterManager ();
91 
~BroadcasterManager()92     ~BroadcasterManager () {}
93 
94     uint32_t
95     RegisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec);
96 
97     bool
98     UnregisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec);
99 
100     Listener *
101     GetListenerForEventSpec (BroadcastEventSpec event_spec) const;
102 
103     void
104     SignUpListenersForBroadcaster (Broadcaster &broadcaster);
105 
106     void
107     RemoveListener (Listener &Listener);
108 
109 protected:
110     void Clear();
111 
112 private:
113     typedef std::pair<BroadcastEventSpec, Listener *> event_listener_key;
114     typedef std::map<BroadcastEventSpec, Listener *> collection;
115     typedef std::set<Listener *> listener_collection;
116     collection m_event_map;
117     listener_collection m_listeners;
118 
119     Mutex m_manager_mutex;
120 
121     // A couple of comparator classes for find_if:
122 
123     class BroadcasterClassMatches
124     {
125     public:
BroadcasterClassMatches(const ConstString & broadcaster_class)126         BroadcasterClassMatches (const ConstString &broadcaster_class) :
127             m_broadcaster_class (broadcaster_class)
128         {
129         }
130 
~BroadcasterClassMatches()131         ~BroadcasterClassMatches () {}
132 
operator()133         bool operator() (const event_listener_key input) const
134         {
135             return (input.first.GetBroadcasterClass() == m_broadcaster_class);
136         }
137 
138     private:
139         ConstString m_broadcaster_class;
140     };
141 
142     class BroadcastEventSpecMatches
143     {
144     public:
BroadcastEventSpecMatches(BroadcastEventSpec broadcaster_spec)145         BroadcastEventSpecMatches (BroadcastEventSpec broadcaster_spec) :
146             m_broadcaster_spec (broadcaster_spec)
147         {
148         }
149 
~BroadcastEventSpecMatches()150         ~BroadcastEventSpecMatches () {}
151 
operator()152         bool operator() (const event_listener_key input) const
153         {
154             return (input.first.IsContainedIn (m_broadcaster_spec));
155         }
156 
157     private:
158         BroadcastEventSpec m_broadcaster_spec;
159     };
160 
161     class ListenerMatchesAndSharedBits
162     {
163     public:
ListenerMatchesAndSharedBits(BroadcastEventSpec broadcaster_spec,const Listener & listener)164         ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec,
165                                                    const Listener &listener) :
166             m_broadcaster_spec (broadcaster_spec),
167             m_listener (&listener)
168         {
169         }
170 
~ListenerMatchesAndSharedBits()171         ~ListenerMatchesAndSharedBits () {}
172 
operator()173         bool operator() (const event_listener_key input) const
174         {
175             return (input.first.GetBroadcasterClass() == m_broadcaster_spec.GetBroadcasterClass()
176                     && (input.first.GetEventBits() & m_broadcaster_spec.GetEventBits()) != 0
177                     && input.second == m_listener);
178         }
179 
180     private:
181         BroadcastEventSpec m_broadcaster_spec;
182         const Listener *m_listener;
183     };
184 
185     class ListenerMatches
186     {
187     public:
ListenerMatches(const Listener & in_listener)188         ListenerMatches (const Listener &in_listener) :
189             m_listener (&in_listener)
190         {
191         }
192 
~ListenerMatches()193         ~ListenerMatches() {}
194 
operator()195         bool operator () (const event_listener_key input) const
196         {
197             if (input.second == m_listener)
198                 return true;
199             else
200                 return false;
201         }
202 
203     private:
204         const Listener *m_listener;
205 
206     };
207 
208 };
209 
210 //----------------------------------------------------------------------
211 /// @class Broadcaster Broadcaster.h "lldb/Core/Broadcaster.h"
212 /// @brief An event broadcasting class.
213 ///
214 /// The Broadcaster class is designed to be subclassed by objects that
215 /// wish to vend events in a multi-threaded environment. Broadcaster
216 /// objects can each vend 32 events. Each event is represented by a bit
217 /// in a 32 bit value and these bits can be set:
218 ///     @see Broadcaster::SetEventBits(uint32_t)
219 /// or cleared:
220 ///     @see Broadcaster::ResetEventBits(uint32_t)
221 /// When an event gets set the Broadcaster object will notify the
222 /// Listener object that is listening for the event (if there is one).
223 ///
224 /// Subclasses should provide broadcast bit definitions for any events
225 /// they vend, typically using an enumeration:
226 ///     \code
227 ///         class Foo : public Broadcaster
228 ///         {
229 ///         public:
230 ///         //----------------------------------------------------------
231 ///         // Broadcaster event bits definitions.
232 ///         //----------------------------------------------------------
233 ///         enum
234 ///         {
235 ///             eBroadcastBitStateChanged   = (1 << 0),
236 ///             eBroadcastBitInterrupt      = (1 << 1),
237 ///             eBroadcastBitSTDOUT         = (1 << 2),
238 ///             eBroadcastBitSTDERR         = (1 << 3),
239 ///             eBroadcastBitProfileData    = (1 << 4)
240 ///         };
241 ///     \endcode
242 //----------------------------------------------------------------------
243 class Broadcaster
244 {
245 public:
246     //------------------------------------------------------------------
247     /// Construct with a broadcaster with a name.
248     ///
249     /// @param[in] name
250     ///     A NULL terminated C string that contains the name of the
251     ///     broadcaster object.
252     //------------------------------------------------------------------
253     Broadcaster (BroadcasterManager *manager, const char *name);
254 
255     //------------------------------------------------------------------
256     /// Destructor.
257     ///
258     /// The destructor is virtual since this class gets subclassed.
259     //------------------------------------------------------------------
260     virtual
261     ~Broadcaster();
262 
263     void
264     CheckInWithManager ();
265 
266     //------------------------------------------------------------------
267     /// Broadcast an event which has no associated data.
268     ///
269     /// @param[in] event_type
270     ///     The element from the enum defining this broadcaster's events
271     ///     that is being broadcast.
272     ///
273     /// @param[in] event_data
274     ///     User event data that will be owned by the lldb::Event that
275     ///     is created internally.
276     ///
277     /// @param[in] unique
278     ///     If true, then only add an event of this type if there isn't
279     ///     one already in the queue.
280     ///
281     //------------------------------------------------------------------
282     void
283     BroadcastEvent (lldb::EventSP &event_sp);
284 
285     void
286     BroadcastEventIfUnique (lldb::EventSP &event_sp);
287 
288     void
289     BroadcastEvent (uint32_t event_type, EventData *event_data = NULL);
290 
291     void
292     BroadcastEventIfUnique (uint32_t event_type, EventData *event_data = NULL);
293 
294     void
295     Clear();
296 
297     virtual void
298     AddInitialEventsToListener (Listener *listener, uint32_t requested_events);
299 
300     //------------------------------------------------------------------
301     /// Listen for any events specified by \a event_mask.
302     ///
303     /// Only one listener can listen to each event bit in a given
304     /// Broadcaster. Once a listener has acquired an event bit, no
305     /// other broadcaster will have access to it until it is
306     /// relinquished by the first listener that gets it. The actual
307     /// event bits that get acquired by \a listener may be different
308     /// from what is requested in \a event_mask, and to track this the
309     /// actual event bits that are acquired get returned.
310     ///
311     /// @param[in] listener
312     ///     The Listener object that wants to monitor the events that
313     ///     get broadcast by this object.
314     ///
315     /// @param[in] event_mask
316     ///     A bit mask that indicates which events the listener is
317     ///     asking to monitor.
318     ///
319     /// @return
320     ///     The actual event bits that were acquired by \a listener.
321     //------------------------------------------------------------------
322     uint32_t
323     AddListener (Listener* listener, uint32_t event_mask);
324 
325     //------------------------------------------------------------------
326     /// Get the NULL terminated C string name of this Broadcaster
327     /// object.
328     ///
329     /// @return
330     ///     The NULL terminated C string name of this Broadcaster.
331     //------------------------------------------------------------------
332     const ConstString &
333     GetBroadcasterName ();
334 
335 
336     //------------------------------------------------------------------
337     /// Get the event name(s) for one or more event bits.
338     ///
339     /// @param[in] event_mask
340     ///     A bit mask that indicates which events to get names for.
341     ///
342     /// @return
343     ///     The NULL terminated C string name of this Broadcaster.
344     //------------------------------------------------------------------
345     bool
346     GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const;
347 
348     //------------------------------------------------------------------
349     /// Set the name for an event bit.
350     ///
351     /// @param[in] event_mask
352     ///     A bit mask that indicates which events the listener is
353     ///     asking to monitor.
354     ///
355     /// @return
356     ///     The NULL terminated C string name of this Broadcaster.
357     //------------------------------------------------------------------
358     void
SetEventName(uint32_t event_mask,const char * name)359     SetEventName (uint32_t event_mask, const char *name)
360     {
361         m_event_names[event_mask] = name;
362     }
363 
364     const char *
GetEventName(uint32_t event_mask)365     GetEventName (uint32_t event_mask) const
366     {
367         event_names_map::const_iterator pos = m_event_names.find (event_mask);
368         if (pos != m_event_names.end())
369             return pos->second.c_str();
370         return NULL;
371     }
372 
373     bool
374     EventTypeHasListeners (uint32_t event_type);
375 
376     //------------------------------------------------------------------
377     /// Removes a Listener from this broadcasters list and frees the
378     /// event bits specified by \a event_mask that were previously
379     /// acquired by \a listener (assuming \a listener was listening to
380     /// this object) for other listener objects to use.
381     ///
382     /// @param[in] listener
383     ///     A Listener object that previously called AddListener.
384     ///
385     /// @param[in] event_mask
386     ///     The event bits \a listener wishes to relinquish.
387     ///
388     /// @return
389     ///     \b True if the listener was listening to this broadcaster
390     ///     and was removed, \b false otherwise.
391     ///
392     /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
393     //------------------------------------------------------------------
394     bool
395     RemoveListener (Listener* listener, uint32_t event_mask = UINT32_MAX);
396 
397     //------------------------------------------------------------------
398     /// Provides a simple mechanism to temporarily redirect events from
399     /// broadcaster.  When you call this function passing in a listener and
400     /// event type mask, all events from the broadcaster matching the mask
401     /// will now go to the hijacking listener.
402     /// Only one hijack can occur at a time.  If we need more than this we
403     /// will have to implement a Listener stack.
404     ///
405     /// @param[in] listener
406     ///     A Listener object.  You do not need to call StartListeningForEvents
407     ///     for this broadcaster (that would fail anyway since the event bits
408     ///     would most likely be taken by the listener(s) you are usurping.
409     ///
410     /// @param[in] event_mask
411     ///     The event bits \a listener wishes to hijack.
412     ///
413     /// @return
414     ///     \b True if the event mask could be hijacked, \b false otherwise.
415     ///
416     /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
417     //------------------------------------------------------------------
418     bool
419     HijackBroadcaster (Listener *listener, uint32_t event_mask = UINT32_MAX);
420 
421     bool
IsHijackedForEvent(uint32_t event_mask)422     IsHijackedForEvent (uint32_t event_mask)
423     {
424         if (m_hijacking_listeners.size() > 0)
425             return (event_mask & m_hijacking_masks.back()) != 0;
426         return false;
427     }
428 
429     //------------------------------------------------------------------
430     /// Restore the state of the Broadcaster from a previous hijack attempt.
431     ///
432     //------------------------------------------------------------------
433     void
434     RestoreBroadcaster ();
435 
436     // This needs to be filled in if you are going to register the broadcaster with the broadcaster
437     // manager and do broadcaster class matching.
438     // FIXME: Probably should make a ManagedBroadcaster subclass with all the bits needed to work
439     // with the BroadcasterManager, so that it is clearer how to add one.
440     virtual ConstString &GetBroadcasterClass() const;
441 
442     BroadcasterManager *GetManager();
443 
444 protected:
445 
446 
447     void
448     PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique);
449 
450     //------------------------------------------------------------------
451     // Classes that inherit from Broadcaster can see and modify these
452     //------------------------------------------------------------------
453     typedef std::vector< std::pair<Listener*,uint32_t> > collection;
454     typedef std::map<uint32_t, std::string> event_names_map;
455     // Prefix the name of our member variables with "m_broadcaster_"
456     // since this is a class that gets subclassed.
457     const ConstString m_broadcaster_name;   ///< The name of this broadcaster object.
458     event_names_map m_event_names;  ///< Optionally define event names for readability and logging for each event bit
459     collection m_listeners;     ///< A list of Listener / event_mask pairs that are listening to this broadcaster.
460     Mutex m_listeners_mutex;    ///< A mutex that protects \a m_listeners.
461     std::vector<Listener *> m_hijacking_listeners;  // A simple mechanism to intercept events from a broadcaster
462     std::vector<uint32_t> m_hijacking_masks;        // At some point we may want to have a stack or Listener
463                                                     // collections, but for now this is just for private hijacking.
464     BroadcasterManager *m_manager;
465 
466 private:
467     //------------------------------------------------------------------
468     // For Broadcaster only
469     //------------------------------------------------------------------
470     DISALLOW_COPY_AND_ASSIGN (Broadcaster);
471 };
472 
473 } // namespace lldb_private
474 
475 #endif  // liblldb_Broadcaster_h_
476