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_
13 #include "lldb/Utility/ConstString.h"
14 #include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN
15 #include "lldb/lldb-forward.h" // for ListenerSP, EventSP, Broadcast...
17 #include "llvm/ADT/SmallVector.h"
19 #include <cstdint> // for uint32_t, UINT32_MAX
21 #include <memory> // for shared_ptr, operator==, enable...
23 #include <set> // for set
25 #include <utility> // for pair
28 namespace lldb_private {
31 namespace lldb_private {
34 namespace lldb_private {
37 namespace lldb_private {
41 namespace lldb_private {
43 //----------------------------------------------------------------------
44 // lldb::BroadcastEventSpec
46 // This class is used to specify a kind of event to register for. The Debugger
47 // maintains a list of BroadcastEventSpec's and when it is made
48 //----------------------------------------------------------------------
49 class BroadcastEventSpec {
51 BroadcastEventSpec(const ConstString &broadcaster_class, uint32_t event_bits)
52 : m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {}
54 BroadcastEventSpec(const BroadcastEventSpec &rhs);
56 ~BroadcastEventSpec() = default;
58 const ConstString &GetBroadcasterClass() const { return m_broadcaster_class; }
60 uint32_t GetEventBits() const { return m_event_bits; }
62 // Tell whether this BroadcastEventSpec is contained in in_spec.
64 // (a) the two spec's share the same broadcaster class
65 // (b) the event bits of this spec are wholly contained in those of in_spec.
66 bool IsContainedIn(BroadcastEventSpec in_spec) const {
67 if (m_broadcaster_class != in_spec.GetBroadcasterClass())
69 uint32_t in_bits = in_spec.GetEventBits();
70 if (in_bits == m_event_bits)
73 if ((m_event_bits & in_bits) != 0 && (m_event_bits & ~in_bits) == 0)
79 bool operator<(const BroadcastEventSpec &rhs) const;
80 BroadcastEventSpec &operator=(const BroadcastEventSpec &rhs);
83 ConstString m_broadcaster_class;
84 uint32_t m_event_bits;
87 class BroadcasterManager
88 : public std::enable_shared_from_this<BroadcasterManager> {
90 friend class Listener;
96 // Listeners hold onto weak pointers to their broadcaster managers. So they
97 // must be made into shared pointers, which you do with
98 // MakeBroadcasterManager.
100 static lldb::BroadcasterManagerSP MakeBroadcasterManager();
102 ~BroadcasterManager() = default;
104 uint32_t RegisterListenerForEvents(const lldb::ListenerSP &listener_sp,
105 BroadcastEventSpec event_spec);
107 bool UnregisterListenerForEvents(const lldb::ListenerSP &listener_sp,
108 BroadcastEventSpec event_spec);
110 lldb::ListenerSP GetListenerForEventSpec(BroadcastEventSpec event_spec) const;
112 void SignUpListenersForBroadcaster(Broadcaster &broadcaster);
114 void RemoveListener(const lldb::ListenerSP &listener_sp);
116 void RemoveListener(Listener *listener);
121 typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key;
122 typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection;
123 typedef std::set<lldb::ListenerSP> listener_collection;
124 collection m_event_map;
125 listener_collection m_listeners;
127 mutable std::recursive_mutex m_manager_mutex;
129 // A couple of comparator classes for find_if:
131 class BroadcasterClassMatches {
133 BroadcasterClassMatches(const ConstString &broadcaster_class)
134 : m_broadcaster_class(broadcaster_class) {}
136 ~BroadcasterClassMatches() = default;
138 bool operator()(const event_listener_key input) const {
139 return (input.first.GetBroadcasterClass() == m_broadcaster_class);
143 ConstString m_broadcaster_class;
146 class BroadcastEventSpecMatches {
148 BroadcastEventSpecMatches(BroadcastEventSpec broadcaster_spec)
149 : m_broadcaster_spec(broadcaster_spec) {}
151 ~BroadcastEventSpecMatches() = default;
153 bool operator()(const event_listener_key input) const {
154 return (input.first.IsContainedIn(m_broadcaster_spec));
158 BroadcastEventSpec m_broadcaster_spec;
161 class ListenerMatchesAndSharedBits {
163 explicit ListenerMatchesAndSharedBits(BroadcastEventSpec broadcaster_spec,
164 const lldb::ListenerSP listener_sp)
165 : m_broadcaster_spec(broadcaster_spec), m_listener_sp(listener_sp) {}
167 ~ListenerMatchesAndSharedBits() = default;
169 bool operator()(const event_listener_key input) const {
170 return (input.first.GetBroadcasterClass() ==
171 m_broadcaster_spec.GetBroadcasterClass() &&
172 (input.first.GetEventBits() &
173 m_broadcaster_spec.GetEventBits()) != 0 &&
174 input.second == m_listener_sp);
178 BroadcastEventSpec m_broadcaster_spec;
179 const lldb::ListenerSP m_listener_sp;
182 class ListenerMatches {
184 explicit ListenerMatches(const lldb::ListenerSP in_listener_sp)
185 : m_listener_sp(in_listener_sp) {}
187 ~ListenerMatches() = default;
189 bool operator()(const event_listener_key input) const {
190 if (input.second == m_listener_sp)
197 const lldb::ListenerSP m_listener_sp;
200 class ListenerMatchesPointer {
202 ListenerMatchesPointer(const Listener *in_listener)
203 : m_listener(in_listener) {}
205 ~ListenerMatchesPointer() = default;
207 bool operator()(const event_listener_key input) const {
208 if (input.second.get() == m_listener)
214 bool operator()(const lldb::ListenerSP input) const {
215 if (input.get() == m_listener)
222 const Listener *m_listener;
226 //----------------------------------------------------------------------
227 /// @class Broadcaster Broadcaster.h "lldb/Core/Broadcaster.h"
228 /// @brief An event broadcasting class.
230 /// The Broadcaster class is designed to be subclassed by objects that
231 /// wish to vend events in a multi-threaded environment. Broadcaster
232 /// objects can each vend 32 events. Each event is represented by a bit
233 /// in a 32 bit value and these bits can be set:
234 /// @see Broadcaster::SetEventBits(uint32_t)
236 /// @see Broadcaster::ResetEventBits(uint32_t)
237 /// When an event gets set the Broadcaster object will notify the
238 /// Listener object that is listening for the event (if there is one).
240 /// Subclasses should provide broadcast bit definitions for any events
241 /// they vend, typically using an enumeration:
243 /// class Foo : public Broadcaster
246 /// //----------------------------------------------------------
247 /// // Broadcaster event bits definitions.
248 /// //----------------------------------------------------------
251 /// eBroadcastBitOne = (1 << 0),
252 /// eBroadcastBitTwo = (1 << 1),
253 /// eBroadcastBitThree = (1 << 2),
257 //----------------------------------------------------------------------
259 friend class Listener;
263 //------------------------------------------------------------------
264 /// Construct with a broadcaster with a name.
267 /// A NULL terminated C string that contains the name of the
268 /// broadcaster object.
269 //------------------------------------------------------------------
270 Broadcaster(lldb::BroadcasterManagerSP manager_sp, const char *name);
272 //------------------------------------------------------------------
275 /// The destructor is virtual since this class gets subclassed.
276 //------------------------------------------------------------------
277 virtual ~Broadcaster();
279 void CheckInWithManager();
281 //------------------------------------------------------------------
282 /// Broadcast an event which has no associated data.
284 /// @param[in] event_type
285 /// The element from the enum defining this broadcaster's events
286 /// that is being broadcast.
288 /// @param[in] event_data
289 /// User event data that will be owned by the lldb::Event that
290 /// is created internally.
292 /// @param[in] unique
293 /// If true, then only add an event of this type if there isn't
294 /// one already in the queue.
296 //------------------------------------------------------------------
297 void BroadcastEvent(lldb::EventSP &event_sp) {
298 m_broadcaster_sp->BroadcastEvent(event_sp);
301 void BroadcastEventIfUnique(lldb::EventSP &event_sp) {
302 m_broadcaster_sp->BroadcastEventIfUnique(event_sp);
305 void BroadcastEvent(uint32_t event_type,
306 const lldb::EventDataSP &event_data_sp) {
307 m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp);
310 void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr) {
311 m_broadcaster_sp->BroadcastEvent(event_type, event_data);
314 void BroadcastEventIfUnique(uint32_t event_type,
315 EventData *event_data = nullptr) {
316 m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data);
319 void Clear() { m_broadcaster_sp->Clear(); }
321 virtual void AddInitialEventsToListener(const lldb::ListenerSP &listener_sp,
322 uint32_t requested_events);
324 //------------------------------------------------------------------
325 /// Listen for any events specified by \a event_mask.
327 /// Only one listener can listen to each event bit in a given
328 /// Broadcaster. Once a listener has acquired an event bit, no
329 /// other broadcaster will have access to it until it is
330 /// relinquished by the first listener that gets it. The actual
331 /// event bits that get acquired by \a listener may be different
332 /// from what is requested in \a event_mask, and to track this the
333 /// actual event bits that are acquired get returned.
335 /// @param[in] listener
336 /// The Listener object that wants to monitor the events that
337 /// get broadcast by this object.
339 /// @param[in] event_mask
340 /// A bit mask that indicates which events the listener is
341 /// asking to monitor.
344 /// The actual event bits that were acquired by \a listener.
345 //------------------------------------------------------------------
346 uint32_t AddListener(const lldb::ListenerSP &listener_sp,
347 uint32_t event_mask) {
348 return m_broadcaster_sp->AddListener(listener_sp, event_mask);
351 //------------------------------------------------------------------
352 /// Get the NULL terminated C string name of this Broadcaster
356 /// The NULL terminated C string name of this Broadcaster.
357 //------------------------------------------------------------------
358 const ConstString &GetBroadcasterName() { return m_broadcaster_name; }
360 //------------------------------------------------------------------
361 /// Get the event name(s) for one or more event bits.
363 /// @param[in] event_mask
364 /// A bit mask that indicates which events to get names for.
367 /// The NULL terminated C string name of this Broadcaster.
368 //------------------------------------------------------------------
369 bool GetEventNames(Stream &s, const uint32_t event_mask,
370 bool prefix_with_broadcaster_name) const {
371 return m_broadcaster_sp->GetEventNames(s, event_mask,
372 prefix_with_broadcaster_name);
375 //------------------------------------------------------------------
376 /// Set the name for an event bit.
378 /// @param[in] event_mask
379 /// A bit mask that indicates which events the listener is
380 /// asking to monitor.
383 /// The NULL terminated C string name of this Broadcaster.
384 //------------------------------------------------------------------
385 void SetEventName(uint32_t event_mask, const char *name) {
386 m_broadcaster_sp->SetEventName(event_mask, name);
389 const char *GetEventName(uint32_t event_mask) const {
390 return m_broadcaster_sp->GetEventName(event_mask);
393 bool EventTypeHasListeners(uint32_t event_type) {
394 return m_broadcaster_sp->EventTypeHasListeners(event_type);
397 //------------------------------------------------------------------
398 /// Removes a Listener from this broadcasters list and frees the
399 /// event bits specified by \a event_mask that were previously
400 /// acquired by \a listener (assuming \a listener was listening to
401 /// this object) for other listener objects to use.
403 /// @param[in] listener
404 /// A Listener object that previously called AddListener.
406 /// @param[in] event_mask
407 /// The event bits \a listener wishes to relinquish.
410 /// \b True if the listener was listening to this broadcaster
411 /// and was removed, \b false otherwise.
413 /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
414 //------------------------------------------------------------------
415 bool RemoveListener(const lldb::ListenerSP &listener_sp,
416 uint32_t event_mask = UINT32_MAX) {
417 return m_broadcaster_sp->RemoveListener(listener_sp, event_mask);
420 //------------------------------------------------------------------
421 /// Provides a simple mechanism to temporarily redirect events from
422 /// broadcaster. When you call this function passing in a listener and
423 /// event type mask, all events from the broadcaster matching the mask
424 /// will now go to the hijacking listener.
425 /// Only one hijack can occur at a time. If we need more than this we
426 /// will have to implement a Listener stack.
428 /// @param[in] listener
429 /// A Listener object. You do not need to call StartListeningForEvents
430 /// for this broadcaster (that would fail anyway since the event bits
431 /// would most likely be taken by the listener(s) you are usurping.
433 /// @param[in] event_mask
434 /// The event bits \a listener wishes to hijack.
437 /// \b True if the event mask could be hijacked, \b false otherwise.
439 /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
440 //------------------------------------------------------------------
441 bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
442 uint32_t event_mask = UINT32_MAX) {
443 return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask);
446 bool IsHijackedForEvent(uint32_t event_mask) {
447 return m_broadcaster_sp->IsHijackedForEvent(event_mask);
450 //------------------------------------------------------------------
451 /// Restore the state of the Broadcaster from a previous hijack attempt.
453 //------------------------------------------------------------------
454 void RestoreBroadcaster() { m_broadcaster_sp->RestoreBroadcaster(); }
456 // This needs to be filled in if you are going to register the broadcaster
457 // with the broadcaster
458 // manager and do broadcaster class matching.
459 // FIXME: Probably should make a ManagedBroadcaster subclass with all the bits
461 // with the BroadcasterManager, so that it is clearer how to add one.
462 virtual ConstString &GetBroadcasterClass() const;
464 lldb::BroadcasterManagerSP GetManager();
467 // BroadcasterImpl contains the actual Broadcaster implementation. The
468 // Broadcaster makes a BroadcasterImpl
469 // which lives as long as it does. The Listeners & the Events hold a weak
470 // pointer to the BroadcasterImpl,
471 // so that they can survive if a Broadcaster they were listening to is
472 // destroyed w/o their being able to
473 // unregister from it (which can happen if the Broadcasters & Listeners are
474 // being destroyed on separate threads
476 // The Broadcaster itself can't be shared out as a weak pointer, because some
477 // things that are broadcasters
478 // (e.g. the Target and the Process) are shared in their own right.
480 // For the most part, the Broadcaster functions dispatch to the
481 // BroadcasterImpl, and are documented in the
482 // public Broadcaster API above.
484 class BroadcasterImpl {
485 friend class Listener;
486 friend class Broadcaster;
489 BroadcasterImpl(Broadcaster &broadcaster);
491 ~BroadcasterImpl() = default;
493 void BroadcastEvent(lldb::EventSP &event_sp);
495 void BroadcastEventIfUnique(lldb::EventSP &event_sp);
497 void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr);
499 void BroadcastEvent(uint32_t event_type,
500 const lldb::EventDataSP &event_data_sp);
502 void BroadcastEventIfUnique(uint32_t event_type,
503 EventData *event_data = nullptr);
507 uint32_t AddListener(const lldb::ListenerSP &listener_sp,
508 uint32_t event_mask);
510 const char *GetBroadcasterName() const {
511 return m_broadcaster.GetBroadcasterName().AsCString();
514 Broadcaster *GetBroadcaster();
516 bool GetEventNames(Stream &s, const uint32_t event_mask,
517 bool prefix_with_broadcaster_name) const;
519 void SetEventName(uint32_t event_mask, const char *name) {
520 m_event_names[event_mask] = name;
523 const char *GetEventName(uint32_t event_mask) const {
524 const auto pos = m_event_names.find(event_mask);
525 if (pos != m_event_names.end())
526 return pos->second.c_str();
530 bool EventTypeHasListeners(uint32_t event_type);
532 bool RemoveListener(lldb_private::Listener *listener,
533 uint32_t event_mask = UINT32_MAX);
535 bool RemoveListener(const lldb::ListenerSP &listener_sp,
536 uint32_t event_mask = UINT32_MAX);
538 bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
539 uint32_t event_mask = UINT32_MAX);
541 bool IsHijackedForEvent(uint32_t event_mask);
543 void RestoreBroadcaster();
546 void PrivateBroadcastEvent(lldb::EventSP &event_sp, bool unique);
548 const char *GetHijackingListenerName();
550 //------------------------------------------------------------------
552 //------------------------------------------------------------------
553 typedef llvm::SmallVector<std::pair<lldb::ListenerWP, uint32_t>, 4>
555 typedef std::map<uint32_t, std::string> event_names_map;
557 llvm::SmallVector<std::pair<lldb::ListenerSP, uint32_t &>, 4>
560 Broadcaster &m_broadcaster; ///< The broadcsater that this implements
561 event_names_map m_event_names; ///< Optionally define event names for
562 ///readability and logging for each event bit
563 collection m_listeners; ///< A list of Listener / event_mask pairs that are
564 ///listening to this broadcaster.
566 m_listeners_mutex; ///< A mutex that protects \a m_listeners.
567 std::vector<lldb::ListenerSP> m_hijacking_listeners; // A simple mechanism
568 // to intercept events
569 // from a broadcaster
570 std::vector<uint32_t> m_hijacking_masks; // At some point we may want to
571 // have a stack or Listener
572 // collections, but for now this is just for private hijacking.
575 //------------------------------------------------------------------
576 // For Broadcaster only
577 //------------------------------------------------------------------
578 DISALLOW_COPY_AND_ASSIGN(BroadcasterImpl);
581 typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP;
582 typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP;
584 BroadcasterImplSP GetBroadcasterImpl() { return m_broadcaster_sp; }
586 const char *GetHijackingListenerName() {
587 return m_broadcaster_sp->GetHijackingListenerName();
589 //------------------------------------------------------------------
590 // Classes that inherit from Broadcaster can see and modify these
591 //------------------------------------------------------------------
594 //------------------------------------------------------------------
595 // For Broadcaster only
596 //------------------------------------------------------------------
597 BroadcasterImplSP m_broadcaster_sp;
598 lldb::BroadcasterManagerSP m_manager_sp;
600 m_broadcaster_name; ///< The name of this broadcaster object.
602 DISALLOW_COPY_AND_ASSIGN(Broadcaster);
605 } // namespace lldb_private
607 #endif // liblldb_Broadcaster_h_