]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/Core/Broadcaster.h
Upgrade to OpenSSH 7.2p2.
[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 <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:
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     
45     ~BroadcastEventSpec() = default;
46         
47     const ConstString &GetBroadcasterClass() const
48     {
49         return m_broadcaster_class;
50     }
51     
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.
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
92     ~BroadcasterManager() = default;
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:
126         BroadcasterClassMatches (const ConstString &broadcaster_class) : 
127             m_broadcaster_class (broadcaster_class) 
128         {
129         }
130         
131         ~BroadcasterClassMatches() = default;
132         
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:
145         BroadcastEventSpecMatches (BroadcastEventSpec broadcaster_spec) : 
146             m_broadcaster_spec (broadcaster_spec) 
147         {
148         }
149         
150         ~BroadcastEventSpecMatches() = default;
151         
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:
164         ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec, 
165                                                    const Listener &listener) : 
166             m_broadcaster_spec (broadcaster_spec),
167             m_listener (&listener) 
168         {
169         }
170         
171         ~ListenerMatchesAndSharedBits() = default;
172         
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:
188         ListenerMatches (const Listener &in_listener) :
189             m_listener (&in_listener)
190         {
191         }
192         
193         ~ListenerMatches() = default;
194         
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 /// @class Broadcaster Broadcaster.h "lldb/Core/Broadcaster.h"
211 /// @brief An event broadcasting class.
212 ///
213 /// The Broadcaster class is designed to be subclassed by objects that
214 /// wish to vend events in a multi-threaded environment. Broadcaster
215 /// objects can each vend 32 events. Each event is represented by a bit
216 /// in a 32 bit value and these bits can be set:
217 ///     @see Broadcaster::SetEventBits(uint32_t)
218 /// or cleared:
219 ///     @see Broadcaster::ResetEventBits(uint32_t)
220 /// When an event gets set the Broadcaster object will notify the
221 /// Listener object that is listening for the event (if there is one).
222 ///
223 /// Subclasses should provide broadcast bit definitions for any events
224 /// they vend, typically using an enumeration:
225 ///     \code
226 ///         class Foo : public Broadcaster
227 ///         {
228 ///         public:
229 ///         //----------------------------------------------------------
230 ///         // Broadcaster event bits definitions.
231 ///         //----------------------------------------------------------
232 ///         enum
233 ///         {
234 ///             eBroadcastBitStateChanged   = (1 << 0),
235 ///             eBroadcastBitInterrupt      = (1 << 1),
236 ///             eBroadcastBitSTDOUT         = (1 << 2),
237 ///             eBroadcastBitSTDERR         = (1 << 3),
238 ///             eBroadcastBitProfileData    = (1 << 4)
239 ///         };
240 ///     \endcode
241 //----------------------------------------------------------------------
242 class Broadcaster
243 {
244 public:
245     //------------------------------------------------------------------
246     /// Construct with a broadcaster with a name.
247     ///
248     /// @param[in] name
249     ///     A NULL terminated C string that contains the name of the
250     ///     broadcaster object.
251     //------------------------------------------------------------------
252     Broadcaster (BroadcasterManager *manager, const char *name);
253
254     //------------------------------------------------------------------
255     /// Destructor.
256     ///
257     /// The destructor is virtual since this class gets subclassed.
258     //------------------------------------------------------------------
259     virtual
260     ~Broadcaster();
261
262     void
263     CheckInWithManager ();
264     
265     //------------------------------------------------------------------
266     /// Broadcast an event which has no associated data.
267     ///
268     /// @param[in] event_type
269     ///     The element from the enum defining this broadcaster's events
270     ///     that is being broadcast.
271     ///
272     /// @param[in] event_data
273     ///     User event data that will be owned by the lldb::Event that
274     ///     is created internally.
275     ///
276     /// @param[in] unique
277     ///     If true, then only add an event of this type if there isn't
278     ///     one already in the queue.
279     ///
280     //------------------------------------------------------------------
281     void
282     BroadcastEvent (lldb::EventSP &event_sp);
283
284     void
285     BroadcastEventIfUnique (lldb::EventSP &event_sp);
286
287     void
288     BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr);
289
290     void
291     BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr);
292
293     void
294     Clear();
295
296     virtual void
297     AddInitialEventsToListener (Listener *listener, uint32_t requested_events);
298
299     //------------------------------------------------------------------
300     /// Listen for any events specified by \a event_mask.
301     ///
302     /// Only one listener can listen to each event bit in a given
303     /// Broadcaster. Once a listener has acquired an event bit, no
304     /// other broadcaster will have access to it until it is
305     /// relinquished by the first listener that gets it. The actual
306     /// event bits that get acquired by \a listener may be different
307     /// from what is requested in \a event_mask, and to track this the
308     /// actual event bits that are acquired get returned.
309     ///
310     /// @param[in] listener
311     ///     The Listener object that wants to monitor the events that
312     ///     get broadcast by this object.
313     ///
314     /// @param[in] event_mask
315     ///     A bit mask that indicates which events the listener is
316     ///     asking to monitor.
317     ///
318     /// @return
319     ///     The actual event bits that were acquired by \a listener.
320     //------------------------------------------------------------------
321     uint32_t
322     AddListener (Listener* listener, uint32_t event_mask);
323
324     //------------------------------------------------------------------
325     /// Get the NULL terminated C string name of this Broadcaster
326     /// object.
327     ///
328     /// @return
329     ///     The NULL terminated C string name of this Broadcaster.
330     //------------------------------------------------------------------
331     const ConstString &
332     GetBroadcasterName ();
333
334     //------------------------------------------------------------------
335     /// Get the event name(s) for one or more event bits.
336     ///
337     /// @param[in] event_mask
338     ///     A bit mask that indicates which events to get names for.
339     ///
340     /// @return
341     ///     The NULL terminated C string name of this Broadcaster.
342     //------------------------------------------------------------------
343     bool
344     GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const;
345
346     //------------------------------------------------------------------
347     /// Set the name for an event bit.
348     ///
349     /// @param[in] event_mask
350     ///     A bit mask that indicates which events the listener is
351     ///     asking to monitor.
352     ///
353     /// @return
354     ///     The NULL terminated C string name of this Broadcaster.
355     //------------------------------------------------------------------
356     void
357     SetEventName (uint32_t event_mask, const char *name)
358     {
359         m_event_names[event_mask] = name;
360     }
361     
362     const char *
363     GetEventName (uint32_t event_mask) const
364     {
365         const auto pos = m_event_names.find (event_mask);
366         if (pos != m_event_names.end())
367             return pos->second.c_str();
368         return nullptr;
369     }
370
371     bool
372     EventTypeHasListeners (uint32_t event_type);
373
374     //------------------------------------------------------------------
375     /// Removes a Listener from this broadcasters list and frees the
376     /// event bits specified by \a event_mask that were previously
377     /// acquired by \a listener (assuming \a listener was listening to
378     /// this object) for other listener objects to use.
379     ///
380     /// @param[in] listener
381     ///     A Listener object that previously called AddListener.
382     ///
383     /// @param[in] event_mask
384     ///     The event bits \a listener wishes to relinquish.
385     ///
386     /// @return
387     ///     \b True if the listener was listening to this broadcaster
388     ///     and was removed, \b false otherwise.
389     ///
390     /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
391     //------------------------------------------------------------------
392     bool
393     RemoveListener (Listener* listener, uint32_t event_mask = UINT32_MAX);
394     
395     //------------------------------------------------------------------
396     /// Provides a simple mechanism to temporarily redirect events from 
397     /// broadcaster.  When you call this function passing in a listener and
398     /// event type mask, all events from the broadcaster matching the mask
399     /// will now go to the hijacking listener.
400     /// Only one hijack can occur at a time.  If we need more than this we
401     /// will have to implement a Listener stack.
402     ///
403     /// @param[in] listener
404     ///     A Listener object.  You do not need to call StartListeningForEvents
405     ///     for this broadcaster (that would fail anyway since the event bits
406     ///     would most likely be taken by the listener(s) you are usurping.
407     ///
408     /// @param[in] event_mask
409     ///     The event bits \a listener wishes to hijack.
410     ///
411     /// @return
412     ///     \b True if the event mask could be hijacked, \b false otherwise.
413     ///
414     /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
415     //------------------------------------------------------------------
416     bool
417     HijackBroadcaster (Listener *listener, uint32_t event_mask = UINT32_MAX);
418     
419     bool
420     IsHijackedForEvent (uint32_t event_mask);
421
422     //------------------------------------------------------------------
423     /// Restore the state of the Broadcaster from a previous hijack attempt.
424     ///
425     //------------------------------------------------------------------
426     void
427     RestoreBroadcaster ();
428     
429     // This needs to be filled in if you are going to register the broadcaster with the broadcaster
430     // manager and do broadcaster class matching.
431     // FIXME: Probably should make a ManagedBroadcaster subclass with all the bits needed to work
432     // with the BroadcasterManager, so that it is clearer how to add one.
433     virtual ConstString &GetBroadcasterClass() const;
434     
435     BroadcasterManager *GetManager();
436
437 protected:
438     void
439     PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique);
440
441     //------------------------------------------------------------------
442     // Classes that inherit from Broadcaster can see and modify these
443     //------------------------------------------------------------------
444     typedef std::vector< std::pair<Listener*,uint32_t> > collection;
445     typedef std::map<uint32_t, std::string> event_names_map;
446     // Prefix the name of our member variables with "m_broadcaster_"
447     // since this is a class that gets subclassed.
448     const ConstString m_broadcaster_name;   ///< The name of this broadcaster object.
449     event_names_map m_event_names;  ///< Optionally define event names for readability and logging for each event bit
450     collection m_listeners;     ///< A list of Listener / event_mask pairs that are listening to this broadcaster.
451     Mutex m_listeners_mutex;    ///< A mutex that protects \a m_listeners.
452     std::vector<Listener *> m_hijacking_listeners;  // A simple mechanism to intercept events from a broadcaster 
453     std::vector<uint32_t> m_hijacking_masks;        // At some point we may want to have a stack or Listener
454                                                     // collections, but for now this is just for private hijacking.
455     BroadcasterManager *m_manager;
456     
457 private:
458     //------------------------------------------------------------------
459     // For Broadcaster only
460     //------------------------------------------------------------------
461     DISALLOW_COPY_AND_ASSIGN (Broadcaster);
462 };
463
464 } // namespace lldb_private
465
466 #endif  // liblldb_Broadcaster_h_