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_
22 // Other libraries and framework includes
24 #include "lldb/lldb-private.h"
25 #include "lldb/Core/ConstString.h"
27 namespace lldb_private {
29 //----------------------------------------------------------------------
30 // lldb::BroadcastEventSpec
32 // This class is used to specify a kind of event to register for. The Debugger
33 // maintains a list of BroadcastEventSpec's and when it is made
34 //----------------------------------------------------------------------
35 class BroadcastEventSpec
38 BroadcastEventSpec (const ConstString &broadcaster_class, uint32_t event_bits) :
39 m_broadcaster_class (broadcaster_class),
40 m_event_bits (event_bits)
44 BroadcastEventSpec (const BroadcastEventSpec &rhs);
46 ~BroadcastEventSpec() = default;
48 const ConstString &GetBroadcasterClass() const
50 return m_broadcaster_class;
53 uint32_t GetEventBits () const
58 // Tell whether this BroadcastEventSpec is contained in in_spec.
60 // (a) the two spec's share the same broadcaster class
61 // (b) the event bits of this spec are wholly contained in those of in_spec.
62 bool IsContainedIn (BroadcastEventSpec in_spec) const
64 if (m_broadcaster_class != in_spec.GetBroadcasterClass())
66 uint32_t in_bits = in_spec.GetEventBits();
67 if (in_bits == m_event_bits)
71 if ((m_event_bits & in_bits) != 0
72 && (m_event_bits & ~in_bits) == 0)
78 bool operator< (const BroadcastEventSpec &rhs) const;
79 BroadcastEventSpec &operator=(const BroadcastEventSpec &rhs);
82 ConstString m_broadcaster_class;
83 uint32_t m_event_bits;
86 class BroadcasterManager :
87 public std::enable_shared_from_this<BroadcasterManager>
90 friend class Listener;
93 BroadcasterManager ();
95 // Listeners hold onto weak pointers to their broadcaster managers. So they must be
96 // made into shared pointers, which you do with MakeBroadcasterManager.
98 static lldb::BroadcasterManagerSP
99 MakeBroadcasterManager();
101 ~BroadcasterManager() = default;
104 RegisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec);
107 UnregisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec);
110 GetListenerForEventSpec (BroadcastEventSpec event_spec) const;
113 SignUpListenersForBroadcaster (Broadcaster &broadcaster);
116 RemoveListener (const lldb::ListenerSP &listener_sp);
119 RemoveListener (Listener *listener);
124 typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key;
125 typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection;
126 typedef std::set<lldb::ListenerSP> listener_collection;
127 collection m_event_map;
128 listener_collection m_listeners;
130 mutable std::recursive_mutex m_manager_mutex;
132 // A couple of comparator classes for find_if:
134 class BroadcasterClassMatches
137 BroadcasterClassMatches (const ConstString &broadcaster_class) :
138 m_broadcaster_class (broadcaster_class)
142 ~BroadcasterClassMatches() = default;
144 bool operator() (const event_listener_key input) const
146 return (input.first.GetBroadcasterClass() == m_broadcaster_class);
150 ConstString m_broadcaster_class;
153 class BroadcastEventSpecMatches
156 BroadcastEventSpecMatches (BroadcastEventSpec broadcaster_spec) :
157 m_broadcaster_spec (broadcaster_spec)
161 ~BroadcastEventSpecMatches() = default;
163 bool operator() (const event_listener_key input) const
165 return (input.first.IsContainedIn (m_broadcaster_spec));
169 BroadcastEventSpec m_broadcaster_spec;
172 class ListenerMatchesAndSharedBits
175 explicit ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec, const lldb::ListenerSP listener_sp) :
176 m_broadcaster_spec (broadcaster_spec),
177 m_listener_sp (listener_sp)
181 ~ListenerMatchesAndSharedBits() = default;
183 bool operator() (const event_listener_key input) const
185 return (input.first.GetBroadcasterClass() == m_broadcaster_spec.GetBroadcasterClass()
186 && (input.first.GetEventBits() & m_broadcaster_spec.GetEventBits()) != 0
187 && input.second == m_listener_sp);
191 BroadcastEventSpec m_broadcaster_spec;
192 const lldb::ListenerSP m_listener_sp;
195 class ListenerMatches
198 explicit ListenerMatches (const lldb::ListenerSP in_listener_sp) :
199 m_listener_sp (in_listener_sp)
203 ~ListenerMatches() = default;
205 bool operator () (const event_listener_key input) const
207 if (input.second == m_listener_sp)
214 const lldb::ListenerSP m_listener_sp;
217 class ListenerMatchesPointer
220 ListenerMatchesPointer (const Listener *in_listener) :
221 m_listener (in_listener)
225 ~ListenerMatchesPointer() = default;
227 bool operator () (const event_listener_key input) const
229 if (input.second.get() == m_listener)
235 bool operator () (const lldb::ListenerSP input) const
237 if (input.get() == m_listener)
244 const Listener *m_listener;
248 //----------------------------------------------------------------------
249 /// @class Broadcaster Broadcaster.h "lldb/Core/Broadcaster.h"
250 /// @brief An event broadcasting class.
252 /// The Broadcaster class is designed to be subclassed by objects that
253 /// wish to vend events in a multi-threaded environment. Broadcaster
254 /// objects can each vend 32 events. Each event is represented by a bit
255 /// in a 32 bit value and these bits can be set:
256 /// @see Broadcaster::SetEventBits(uint32_t)
258 /// @see Broadcaster::ResetEventBits(uint32_t)
259 /// When an event gets set the Broadcaster object will notify the
260 /// Listener object that is listening for the event (if there is one).
262 /// Subclasses should provide broadcast bit definitions for any events
263 /// they vend, typically using an enumeration:
265 /// class Foo : public Broadcaster
268 /// //----------------------------------------------------------
269 /// // Broadcaster event bits definitions.
270 /// //----------------------------------------------------------
273 /// eBroadcastBitStateChanged = (1 << 0),
274 /// eBroadcastBitInterrupt = (1 << 1),
275 /// eBroadcastBitSTDOUT = (1 << 2),
276 /// eBroadcastBitSTDERR = (1 << 3),
277 /// eBroadcastBitProfileData = (1 << 4)
280 //----------------------------------------------------------------------
283 friend class Listener;
286 //------------------------------------------------------------------
287 /// Construct with a broadcaster with a name.
290 /// A NULL terminated C string that contains the name of the
291 /// broadcaster object.
292 //------------------------------------------------------------------
293 Broadcaster (lldb::BroadcasterManagerSP manager_sp, const char *name);
295 //------------------------------------------------------------------
298 /// The destructor is virtual since this class gets subclassed.
299 //------------------------------------------------------------------
304 CheckInWithManager ();
306 //------------------------------------------------------------------
307 /// Broadcast an event which has no associated data.
309 /// @param[in] event_type
310 /// The element from the enum defining this broadcaster's events
311 /// that is being broadcast.
313 /// @param[in] event_data
314 /// User event data that will be owned by the lldb::Event that
315 /// is created internally.
317 /// @param[in] unique
318 /// If true, then only add an event of this type if there isn't
319 /// one already in the queue.
321 //------------------------------------------------------------------
323 BroadcastEvent (lldb::EventSP &event_sp)
325 m_broadcaster_sp->BroadcastEvent(event_sp);
329 BroadcastEventIfUnique (lldb::EventSP &event_sp)
331 m_broadcaster_sp->BroadcastEventIfUnique(event_sp);
335 BroadcastEvent(uint32_t event_type, const lldb::EventDataSP &event_data_sp)
337 m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp);
341 BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr)
343 m_broadcaster_sp->BroadcastEvent(event_type, event_data);
347 BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr)
349 m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data);
355 m_broadcaster_sp->Clear();
359 AddInitialEventsToListener (const lldb::ListenerSP &listener_sp, uint32_t requested_events);
361 //------------------------------------------------------------------
362 /// Listen for any events specified by \a event_mask.
364 /// Only one listener can listen to each event bit in a given
365 /// Broadcaster. Once a listener has acquired an event bit, no
366 /// other broadcaster will have access to it until it is
367 /// relinquished by the first listener that gets it. The actual
368 /// event bits that get acquired by \a listener may be different
369 /// from what is requested in \a event_mask, and to track this the
370 /// actual event bits that are acquired get returned.
372 /// @param[in] listener
373 /// The Listener object that wants to monitor the events that
374 /// get broadcast by this object.
376 /// @param[in] event_mask
377 /// A bit mask that indicates which events the listener is
378 /// asking to monitor.
381 /// The actual event bits that were acquired by \a listener.
382 //------------------------------------------------------------------
384 AddListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask)
386 return m_broadcaster_sp->AddListener(listener_sp, event_mask);
389 //------------------------------------------------------------------
390 /// Get the NULL terminated C string name of this Broadcaster
394 /// The NULL terminated C string name of this Broadcaster.
395 //------------------------------------------------------------------
397 GetBroadcasterName ()
399 return m_broadcaster_name;
402 //------------------------------------------------------------------
403 /// Get the event name(s) for one or more event bits.
405 /// @param[in] event_mask
406 /// A bit mask that indicates which events to get names for.
409 /// The NULL terminated C string name of this Broadcaster.
410 //------------------------------------------------------------------
412 GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const
414 return m_broadcaster_sp->GetEventNames(s, event_mask, prefix_with_broadcaster_name);
417 //------------------------------------------------------------------
418 /// Set the name for an event bit.
420 /// @param[in] event_mask
421 /// A bit mask that indicates which events the listener is
422 /// asking to monitor.
425 /// The NULL terminated C string name of this Broadcaster.
426 //------------------------------------------------------------------
428 SetEventName (uint32_t event_mask, const char *name)
430 m_broadcaster_sp->SetEventName(event_mask, name);
434 GetEventName (uint32_t event_mask) const
436 return m_broadcaster_sp->GetEventName(event_mask);
440 EventTypeHasListeners (uint32_t event_type)
442 return m_broadcaster_sp->EventTypeHasListeners(event_type);
445 //------------------------------------------------------------------
446 /// Removes a Listener from this broadcasters list and frees the
447 /// event bits specified by \a event_mask that were previously
448 /// acquired by \a listener (assuming \a listener was listening to
449 /// this object) for other listener objects to use.
451 /// @param[in] listener
452 /// A Listener object that previously called AddListener.
454 /// @param[in] event_mask
455 /// The event bits \a listener wishes to relinquish.
458 /// \b True if the listener was listening to this broadcaster
459 /// and was removed, \b false otherwise.
461 /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
462 //------------------------------------------------------------------
464 RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX)
466 return m_broadcaster_sp->RemoveListener(listener_sp, event_mask);
469 //------------------------------------------------------------------
470 /// Provides a simple mechanism to temporarily redirect events from
471 /// broadcaster. When you call this function passing in a listener and
472 /// event type mask, all events from the broadcaster matching the mask
473 /// will now go to the hijacking listener.
474 /// Only one hijack can occur at a time. If we need more than this we
475 /// will have to implement a Listener stack.
477 /// @param[in] listener
478 /// A Listener object. You do not need to call StartListeningForEvents
479 /// for this broadcaster (that would fail anyway since the event bits
480 /// would most likely be taken by the listener(s) you are usurping.
482 /// @param[in] event_mask
483 /// The event bits \a listener wishes to hijack.
486 /// \b True if the event mask could be hijacked, \b false otherwise.
488 /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
489 //------------------------------------------------------------------
491 HijackBroadcaster (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX)
493 return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask);
497 IsHijackedForEvent (uint32_t event_mask)
499 return m_broadcaster_sp->IsHijackedForEvent(event_mask);
502 //------------------------------------------------------------------
503 /// Restore the state of the Broadcaster from a previous hijack attempt.
505 //------------------------------------------------------------------
507 RestoreBroadcaster ()
509 m_broadcaster_sp->RestoreBroadcaster();
512 // This needs to be filled in if you are going to register the broadcaster with the broadcaster
513 // manager and do broadcaster class matching.
514 // FIXME: Probably should make a ManagedBroadcaster subclass with all the bits needed to work
515 // with the BroadcasterManager, so that it is clearer how to add one.
516 virtual ConstString &GetBroadcasterClass() const;
518 lldb::BroadcasterManagerSP GetManager();
521 // BroadcasterImpl contains the actual Broadcaster implementation. The Broadcaster makes a BroadcasterImpl
522 // which lives as long as it does. The Listeners & the Events hold a weak pointer to the BroadcasterImpl,
523 // so that they can survive if a Broadcaster they were listening to is destroyed w/o their being able to
524 // unregister from it (which can happen if the Broadcasters & Listeners are being destroyed on separate threads
526 // The Broadcaster itself can't be shared out as a weak pointer, because some things that are broadcasters
527 // (e.g. the Target and the Process) are shared in their own right.
529 // For the most part, the Broadcaster functions dispatch to the BroadcasterImpl, and are documented in the
530 // public Broadcaster API above.
533 class BroadcasterImpl
535 friend class Listener;
536 friend class Broadcaster;
538 BroadcasterImpl (Broadcaster &broadcaster);
540 ~BroadcasterImpl() = default;
543 BroadcastEvent (lldb::EventSP &event_sp);
546 BroadcastEventIfUnique (lldb::EventSP &event_sp);
549 BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr);
552 BroadcastEvent(uint32_t event_type, const lldb::EventDataSP &event_data_sp);
555 BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr);
561 AddListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask);
564 GetBroadcasterName () const
566 return m_broadcaster.GetBroadcasterName().AsCString();
573 GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const;
576 SetEventName (uint32_t event_mask, const char *name)
578 m_event_names[event_mask] = name;
582 GetEventName (uint32_t event_mask) const
584 const auto pos = m_event_names.find (event_mask);
585 if (pos != m_event_names.end())
586 return pos->second.c_str();
591 EventTypeHasListeners (uint32_t event_type);
594 RemoveListener (lldb_private::Listener *listener, uint32_t event_mask = UINT32_MAX);
597 RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX);
600 HijackBroadcaster (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX);
603 IsHijackedForEvent (uint32_t event_mask);
606 RestoreBroadcaster ();
610 PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique);
613 GetHijackingListenerName();
615 //------------------------------------------------------------------
617 //------------------------------------------------------------------
618 typedef std::list< std::pair<lldb::ListenerWP,uint32_t> > collection;
619 typedef std::map<uint32_t, std::string> event_names_map;
622 ListenerIterator (std::function <bool (const lldb::ListenerSP &listener_sp, uint32_t &event_mask)> const &callback);
625 Broadcaster &m_broadcaster; ///< The broadcsater that this implements
626 event_names_map m_event_names; ///< Optionally define event names for readability and logging for each event bit
627 collection m_listeners; ///< A list of Listener / event_mask pairs that are listening to this broadcaster.
628 std::recursive_mutex m_listeners_mutex; ///< A mutex that protects \a m_listeners.
629 std::vector<lldb::ListenerSP> m_hijacking_listeners; // A simple mechanism to intercept events from a broadcaster
630 std::vector<uint32_t> m_hijacking_masks; // At some point we may want to have a stack or Listener
631 // collections, but for now this is just for private hijacking.
634 //------------------------------------------------------------------
635 // For Broadcaster only
636 //------------------------------------------------------------------
637 DISALLOW_COPY_AND_ASSIGN (BroadcasterImpl);
640 typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP;
641 typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP;
646 return m_broadcaster_sp;
650 GetHijackingListenerName()
652 return m_broadcaster_sp->GetHijackingListenerName();
654 //------------------------------------------------------------------
655 // Classes that inherit from Broadcaster can see and modify these
656 //------------------------------------------------------------------
660 //------------------------------------------------------------------
661 // For Broadcaster only
662 //------------------------------------------------------------------
663 BroadcasterImplSP m_broadcaster_sp;
664 lldb::BroadcasterManagerSP m_manager_sp;
665 const ConstString m_broadcaster_name; ///< The name of this broadcaster object.
667 DISALLOW_COPY_AND_ASSIGN (Broadcaster);
670 } // namespace lldb_private
672 #endif // liblldb_Broadcaster_h_