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    friend class Listener;
89
90    BroadcasterManager ();
91
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
109protected:
110    void Clear();
111
112private:
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 () {}
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 () {}
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 () {}
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() {}
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//----------------------------------------------------------------------
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//----------------------------------------------------------------------
243class Broadcaster
244{
245public:
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
359    SetEventName (uint32_t event_mask, const char *name)
360    {
361        m_event_names[event_mask] = name;
362    }
363
364    const char *
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
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
444protected:
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
466private:
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