1 //===-- Broadcaster.h -------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_Broadcaster_h_
11 #define liblldb_Broadcaster_h_
19 // Other libraries and framework 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"
26 namespace lldb_private {
28 //----------------------------------------------------------------------
29 // lldb::BroadcastEventSpec
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
37 BroadcastEventSpec (const ConstString &broadcaster_class, uint32_t event_bits) :
38 m_broadcaster_class (broadcaster_class),
39 m_event_bits (event_bits)
43 BroadcastEventSpec (const BroadcastEventSpec &rhs);
45 ~BroadcastEventSpec() {}
47 const ConstString &GetBroadcasterClass() const
49 return m_broadcaster_class;
52 uint32_t GetEventBits () const
57 // Tell whether this BroadcastEventSpec is contained in in_spec.
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
63 if (m_broadcaster_class != in_spec.GetBroadcasterClass())
65 uint32_t in_bits = in_spec.GetEventBits();
66 if (in_bits == m_event_bits)
70 if ((m_event_bits & in_bits) != 0
71 && (m_event_bits & ~in_bits) == 0)
77 bool operator< (const BroadcastEventSpec &rhs) const;
78 const BroadcastEventSpec &operator= (const BroadcastEventSpec &rhs);
81 ConstString m_broadcaster_class;
82 uint32_t m_event_bits;
85 class BroadcasterManager
88 friend class Listener;
90 BroadcasterManager ();
92 ~BroadcasterManager () {}
95 RegisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec);
98 UnregisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec);
101 GetListenerForEventSpec (BroadcastEventSpec event_spec) const;
104 SignUpListenersForBroadcaster (Broadcaster &broadcaster);
107 RemoveListener (Listener &Listener);
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;
119 Mutex m_manager_mutex;
121 // A couple of comparator classes for find_if:
123 class BroadcasterClassMatches
126 BroadcasterClassMatches (const ConstString &broadcaster_class) :
127 m_broadcaster_class (broadcaster_class)
131 ~BroadcasterClassMatches () {}
133 bool operator() (const event_listener_key input) const
135 return (input.first.GetBroadcasterClass() == m_broadcaster_class);
139 ConstString m_broadcaster_class;
142 class BroadcastEventSpecMatches
145 BroadcastEventSpecMatches (BroadcastEventSpec broadcaster_spec) :
146 m_broadcaster_spec (broadcaster_spec)
150 ~BroadcastEventSpecMatches () {}
152 bool operator() (const event_listener_key input) const
154 return (input.first.IsContainedIn (m_broadcaster_spec));
158 BroadcastEventSpec m_broadcaster_spec;
161 class ListenerMatchesAndSharedBits
164 ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec,
165 const Listener &listener) :
166 m_broadcaster_spec (broadcaster_spec),
167 m_listener (&listener)
171 ~ListenerMatchesAndSharedBits () {}
173 bool operator() (const event_listener_key input) const
175 return (input.first.GetBroadcasterClass() == m_broadcaster_spec.GetBroadcasterClass()
176 && (input.first.GetEventBits() & m_broadcaster_spec.GetEventBits()) != 0
177 && input.second == m_listener);
181 BroadcastEventSpec m_broadcaster_spec;
182 const Listener *m_listener;
185 class ListenerMatches
188 ListenerMatches (const Listener &in_listener) :
189 m_listener (&in_listener)
193 ~ListenerMatches() {}
195 bool operator () (const event_listener_key input) const
197 if (input.second == m_listener)
204 const Listener *m_listener;
210 //----------------------------------------------------------------------
211 /// @class Broadcaster Broadcaster.h "lldb/Core/Broadcaster.h"
212 /// @brief An event broadcasting class.
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)
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).
224 /// Subclasses should provide broadcast bit definitions for any events
225 /// they vend, typically using an enumeration:
227 /// class Foo : public Broadcaster
230 /// //----------------------------------------------------------
231 /// // Broadcaster event bits definitions.
232 /// //----------------------------------------------------------
235 /// eBroadcastBitStateChanged = (1 << 0),
236 /// eBroadcastBitInterrupt = (1 << 1),
237 /// eBroadcastBitSTDOUT = (1 << 2),
238 /// eBroadcastBitSTDERR = (1 << 3),
239 /// eBroadcastBitProfileData = (1 << 4)
242 //----------------------------------------------------------------------
246 //------------------------------------------------------------------
247 /// Construct with a broadcaster with a name.
250 /// A NULL terminated C string that contains the name of the
251 /// broadcaster object.
252 //------------------------------------------------------------------
253 Broadcaster (BroadcasterManager *manager, const char *name);
255 //------------------------------------------------------------------
258 /// The destructor is virtual since this class gets subclassed.
259 //------------------------------------------------------------------
264 CheckInWithManager ();
266 //------------------------------------------------------------------
267 /// Broadcast an event which has no associated data.
269 /// @param[in] event_type
270 /// The element from the enum defining this broadcaster's events
271 /// that is being broadcast.
273 /// @param[in] event_data
274 /// User event data that will be owned by the lldb::Event that
275 /// is created internally.
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.
281 //------------------------------------------------------------------
283 BroadcastEvent (lldb::EventSP &event_sp);
286 BroadcastEventIfUnique (lldb::EventSP &event_sp);
289 BroadcastEvent (uint32_t event_type, EventData *event_data = NULL);
292 BroadcastEventIfUnique (uint32_t event_type, EventData *event_data = NULL);
298 AddInitialEventsToListener (Listener *listener, uint32_t requested_events);
300 //------------------------------------------------------------------
301 /// Listen for any events specified by \a event_mask.
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.
311 /// @param[in] listener
312 /// The Listener object that wants to monitor the events that
313 /// get broadcast by this object.
315 /// @param[in] event_mask
316 /// A bit mask that indicates which events the listener is
317 /// asking to monitor.
320 /// The actual event bits that were acquired by \a listener.
321 //------------------------------------------------------------------
323 AddListener (Listener* listener, uint32_t event_mask);
325 //------------------------------------------------------------------
326 /// Get the NULL terminated C string name of this Broadcaster
330 /// The NULL terminated C string name of this Broadcaster.
331 //------------------------------------------------------------------
333 GetBroadcasterName ();
336 //------------------------------------------------------------------
337 /// Get the event name(s) for one or more event bits.
339 /// @param[in] event_mask
340 /// A bit mask that indicates which events to get names for.
343 /// The NULL terminated C string name of this Broadcaster.
344 //------------------------------------------------------------------
346 GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const;
348 //------------------------------------------------------------------
349 /// Set the name for an event bit.
351 /// @param[in] event_mask
352 /// A bit mask that indicates which events the listener is
353 /// asking to monitor.
356 /// The NULL terminated C string name of this Broadcaster.
357 //------------------------------------------------------------------
359 SetEventName (uint32_t event_mask, const char *name)
361 m_event_names[event_mask] = name;
365 GetEventName (uint32_t event_mask) const
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();
374 EventTypeHasListeners (uint32_t event_type);
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.
382 /// @param[in] listener
383 /// A Listener object that previously called AddListener.
385 /// @param[in] event_mask
386 /// The event bits \a listener wishes to relinquish.
389 /// \b True if the listener was listening to this broadcaster
390 /// and was removed, \b false otherwise.
392 /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
393 //------------------------------------------------------------------
395 RemoveListener (Listener* listener, uint32_t event_mask = UINT32_MAX);
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.
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.
410 /// @param[in] event_mask
411 /// The event bits \a listener wishes to hijack.
414 /// \b True if the event mask could be hijacked, \b false otherwise.
416 /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
417 //------------------------------------------------------------------
419 HijackBroadcaster (Listener *listener, uint32_t event_mask = UINT32_MAX);
422 IsHijackedForEvent (uint32_t event_mask)
424 if (m_hijacking_listeners.size() > 0)
425 return (event_mask & m_hijacking_masks.back()) != 0;
429 //------------------------------------------------------------------
430 /// Restore the state of the Broadcaster from a previous hijack attempt.
432 //------------------------------------------------------------------
434 RestoreBroadcaster ();
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;
442 BroadcasterManager *GetManager();
448 PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique);
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;
467 //------------------------------------------------------------------
468 // For Broadcaster only
469 //------------------------------------------------------------------
470 DISALLOW_COPY_AND_ASSIGN (Broadcaster);
473 } // namespace lldb_private
475 #endif // liblldb_Broadcaster_h_