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