Home | History | Annotate | Download | only in Core
      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() {}
     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 () {}
     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 () {}
    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 //----------------------------------------------------------------------
    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
    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 
    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