Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:56

0001 //===-- Broadcaster.h -------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_UTILITY_BROADCASTER_H
0010 #define LLDB_UTILITY_BROADCASTER_H
0011 
0012 #include "lldb/Utility/ConstString.h"
0013 #include "lldb/lldb-defines.h"
0014 #include "lldb/lldb-forward.h"
0015 
0016 #include "llvm/ADT/SmallVector.h"
0017 
0018 #include <cstdint>
0019 #include <map>
0020 #include <memory>
0021 #include <mutex>
0022 #include <set>
0023 #include <string>
0024 #include <utility>
0025 #include <vector>
0026 
0027 namespace lldb_private {
0028 class Broadcaster;
0029 class EventData;
0030 class Listener;
0031 class Stream;
0032 } // namespace lldb_private
0033 
0034 namespace lldb_private {
0035 
0036 /// lldb::BroadcastEventSpec
0037 ///
0038 /// This class is used to specify a kind of event to register for.  The
0039 /// Debugger maintains a list of BroadcastEventSpec's and when it is made
0040 class BroadcastEventSpec {
0041 public:
0042   BroadcastEventSpec(llvm::StringRef broadcaster_class, uint32_t event_bits)
0043       : m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {}
0044 
0045   ~BroadcastEventSpec() = default;
0046 
0047   const std::string &GetBroadcasterClass() const { return m_broadcaster_class; }
0048 
0049   uint32_t GetEventBits() const { return m_event_bits; }
0050 
0051   /// Tell whether this BroadcastEventSpec is contained in in_spec. That is:
0052   /// (a) the two spec's share the same broadcaster class (b) the event bits of
0053   /// this spec are wholly contained in those of in_spec.
0054   bool IsContainedIn(const BroadcastEventSpec &in_spec) const {
0055     if (m_broadcaster_class != in_spec.GetBroadcasterClass())
0056       return false;
0057     uint32_t in_bits = in_spec.GetEventBits();
0058     if (in_bits == m_event_bits)
0059       return true;
0060 
0061     if ((m_event_bits & in_bits) != 0 && (m_event_bits & ~in_bits) == 0)
0062       return true;
0063 
0064     return false;
0065   }
0066 
0067   bool operator<(const BroadcastEventSpec &rhs) const;
0068 
0069 private:
0070   std::string m_broadcaster_class;
0071   uint32_t m_event_bits;
0072 };
0073 
0074 class BroadcasterManager
0075     : public std::enable_shared_from_this<BroadcasterManager> {
0076 public:
0077   friend class Listener;
0078 
0079 protected:
0080   BroadcasterManager();
0081 
0082 public:
0083   /// Listeners hold onto weak pointers to their broadcaster managers.  So they
0084   /// must be made into shared pointers, which you do with
0085   /// MakeBroadcasterManager.
0086   static lldb::BroadcasterManagerSP MakeBroadcasterManager();
0087 
0088   ~BroadcasterManager() = default;
0089 
0090   lldb::ListenerSP
0091   GetListenerForEventSpec(const BroadcastEventSpec &event_spec) const;
0092 
0093   void SignUpListenersForBroadcaster(Broadcaster &broadcaster);
0094 
0095   void RemoveListener(const lldb::ListenerSP &listener_sp);
0096 
0097   void RemoveListener(Listener *listener);
0098 
0099   void Clear();
0100 
0101 private:
0102   uint32_t
0103   RegisterListenerForEventsNoLock(const lldb::ListenerSP &listener_sp,
0104                                   const BroadcastEventSpec &event_spec);
0105 
0106   bool UnregisterListenerForEventsNoLock(const lldb::ListenerSP &listener_sp,
0107                                          const BroadcastEventSpec &event_spec);
0108 
0109   typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key;
0110   typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection;
0111   typedef std::set<lldb::ListenerSP> listener_collection;
0112   collection m_event_map;
0113   listener_collection m_listeners;
0114 
0115   mutable std::mutex m_manager_mutex;
0116 };
0117 
0118 /// \class Broadcaster Broadcaster.h "lldb/Utility/Broadcaster.h" An event
0119 /// broadcasting class.
0120 ///
0121 /// The Broadcaster class is designed to be subclassed by objects that wish to
0122 /// vend events in a multi-threaded environment. Broadcaster objects can each
0123 /// vend 32 events. Each event is represented by a bit in a 32 bit value and
0124 /// these bits can be set:
0125 ///     \see Broadcaster::SetEventBits(uint32_t)
0126 /// or cleared:
0127 ///     \see Broadcaster::ResetEventBits(uint32_t)
0128 /// When an event gets set the Broadcaster object will notify the Listener
0129 /// object that is listening for the event (if there is one).
0130 ///
0131 /// Subclasses should provide broadcast bit definitions for any events they
0132 /// vend, typically using an enumeration:
0133 ///     \code
0134 ///         class Foo : public Broadcaster
0135 ///         {
0136 ///         public:
0137 ///         // Broadcaster event bits definitions.
0138 ///         enum
0139 ///         {
0140 ///             eBroadcastBitOne   = (1 << 0),
0141 ///             eBroadcastBitTwo   = (1 << 1),
0142 ///             eBroadcastBitThree = (1 << 2),
0143 ///             ...
0144 ///         };
0145 ///     \endcode
0146 class Broadcaster {
0147   friend class Listener;
0148   friend class Event;
0149 
0150 public:
0151   /// Construct with a broadcaster with a name.
0152   ///
0153   /// \param[in] manager_sp
0154   ///   A shared pointer to the BroadcasterManager that will manage this
0155   ///   broadcaster.
0156   /// \param[in] name
0157   ///   A std::string of the name that this broadcaster will have.
0158   Broadcaster(lldb::BroadcasterManagerSP manager_sp, std::string name);
0159 
0160   /// Destructor.
0161   ///
0162   /// The destructor is virtual since this class gets subclassed.
0163   virtual ~Broadcaster();
0164 
0165   void CheckInWithManager();
0166 
0167   /// Broadcast an event which has no associated data.
0168   void BroadcastEvent(lldb::EventSP &event_sp) {
0169     m_broadcaster_sp->BroadcastEvent(event_sp);
0170   }
0171 
0172   void BroadcastEventIfUnique(lldb::EventSP &event_sp) {
0173     m_broadcaster_sp->BroadcastEventIfUnique(event_sp);
0174   }
0175 
0176   void BroadcastEvent(uint32_t event_type,
0177                       const lldb::EventDataSP &event_data_sp) {
0178     m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp);
0179   }
0180 
0181   void BroadcastEvent(uint32_t event_type) {
0182     m_broadcaster_sp->BroadcastEvent(event_type);
0183   }
0184 
0185   void BroadcastEventIfUnique(uint32_t event_type) {
0186     m_broadcaster_sp->BroadcastEventIfUnique(event_type);
0187   }
0188 
0189   void Clear() { m_broadcaster_sp->Clear(); }
0190 
0191   virtual void AddInitialEventsToListener(const lldb::ListenerSP &listener_sp,
0192                                           uint32_t requested_events);
0193 
0194   /// Listen for any events specified by \a event_mask.
0195   ///
0196   /// Only one listener can listen to each event bit in a given Broadcaster.
0197   /// Once a listener has acquired an event bit, no other broadcaster will
0198   /// have access to it until it is relinquished by the first listener that
0199   /// gets it. The actual event bits that get acquired by \a listener may be
0200   /// different from what is requested in \a event_mask, and to track this the
0201   /// actual event bits that are acquired get returned.
0202   ///
0203   /// \param[in] listener_sp
0204   ///     The Listener object that wants to monitor the events that
0205   ///     get broadcast by this object.
0206   ///
0207   /// \param[in] event_mask
0208   ///     A bit mask that indicates which events the listener is
0209   ///     asking to monitor.
0210   ///
0211   /// \return
0212   ///     The actual event bits that were acquired by \a listener.
0213   uint32_t AddListener(const lldb::ListenerSP &listener_sp,
0214                        uint32_t event_mask) {
0215     return m_broadcaster_sp->AddListener(listener_sp, event_mask);
0216   }
0217 
0218   /// Get this broadcaster's name.
0219   ///
0220   /// \return
0221   ///     A reference to a constant std::string containing the name of the
0222   ///     broadcaster.
0223   const std::string &GetBroadcasterName() { return m_broadcaster_name; }
0224 
0225   /// Get the event name(s) for one or more event bits.
0226   ///
0227   /// \param[in] event_mask
0228   ///     A bit mask that indicates which events to get names for.
0229   ///
0230   /// \return
0231   ///     The NULL terminated C string name of this Broadcaster.
0232   bool GetEventNames(Stream &s, const uint32_t event_mask,
0233                      bool prefix_with_broadcaster_name) const {
0234     return m_broadcaster_sp->GetEventNames(s, event_mask,
0235                                            prefix_with_broadcaster_name);
0236   }
0237 
0238   /// Set the name for an event bit.
0239   ///
0240   /// \param[in] event_mask
0241   ///     A bit mask that indicates which events the listener is
0242   ///     asking to monitor.
0243   void SetEventName(uint32_t event_mask, const char *name) {
0244     m_broadcaster_sp->SetEventName(event_mask, name);
0245   }
0246 
0247   const char *GetEventName(uint32_t event_mask) const {
0248     return m_broadcaster_sp->GetEventName(event_mask);
0249   }
0250 
0251   bool EventTypeHasListeners(uint32_t event_type) {
0252     return m_broadcaster_sp->EventTypeHasListeners(event_type);
0253   }
0254 
0255   /// Removes a Listener from this broadcasters list and frees the event bits
0256   /// specified by \a event_mask that were previously acquired by \a listener
0257   /// (assuming \a listener was listening to this object) for other listener
0258   /// objects to use.
0259   ///
0260   /// \param[in] listener_sp
0261   ///     A Listener object that previously called AddListener.
0262   ///
0263   /// \param[in] event_mask
0264   ///     The event bits \a listener wishes to relinquish.
0265   ///
0266   /// \return
0267   ///     \b True if the listener was listening to this broadcaster
0268   ///     and was removed, \b false otherwise.
0269   ///
0270   /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
0271   bool RemoveListener(const lldb::ListenerSP &listener_sp,
0272                       uint32_t event_mask = UINT32_MAX) {
0273     return m_broadcaster_sp->RemoveListener(listener_sp, event_mask);
0274   }
0275 
0276   /// Provides a simple mechanism to temporarily redirect events from
0277   /// broadcaster.  When you call this function passing in a listener and
0278   /// event type mask, all events from the broadcaster matching the mask will
0279   /// now go to the hijacking listener. Only one hijack can occur at a time.
0280   /// If we need more than this we will have to implement a Listener stack.
0281   ///
0282   /// \param[in] listener_sp
0283   ///     A Listener object.  You do not need to call StartListeningForEvents
0284   ///     for this broadcaster (that would fail anyway since the event bits
0285   ///     would most likely be taken by the listener(s) you are usurping.
0286   ///
0287   /// \param[in] event_mask
0288   ///     The event bits \a listener wishes to hijack.
0289   ///
0290   /// \return
0291   ///     \b True if the event mask could be hijacked, \b false otherwise.
0292   ///
0293   /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
0294   bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
0295                          uint32_t event_mask = UINT32_MAX) {
0296     return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask);
0297   }
0298 
0299   bool IsHijackedForEvent(uint32_t event_mask) {
0300     return m_broadcaster_sp->IsHijackedForEvent(event_mask);
0301   }
0302 
0303   /// Restore the state of the Broadcaster from a previous hijack attempt.
0304   void RestoreBroadcaster() { m_broadcaster_sp->RestoreBroadcaster(); }
0305 
0306   /// This needs to be filled in if you are going to register the broadcaster
0307   /// with the broadcaster manager and do broadcaster class matching.
0308   /// FIXME: Probably should make a ManagedBroadcaster subclass with all the
0309   /// bits needed to work with the BroadcasterManager, so that it is clearer
0310   /// how to add one.
0311   virtual llvm::StringRef GetBroadcasterClass() const;
0312 
0313   lldb::BroadcasterManagerSP GetManager();
0314 
0315   void SetPrimaryListener(lldb::ListenerSP listener_sp) {
0316     m_broadcaster_sp->SetPrimaryListener(listener_sp);
0317   }
0318 
0319   lldb::ListenerSP GetPrimaryListener() {
0320     return m_broadcaster_sp->m_primary_listener_sp;
0321   }
0322 
0323 protected:
0324   /// BroadcasterImpl contains the actual Broadcaster implementation.  The
0325   /// Broadcaster makes a BroadcasterImpl which lives as long as it does.  The
0326   /// Listeners & the Events hold a weak pointer to the BroadcasterImpl, so
0327   /// that they can survive if a Broadcaster they were listening to is
0328   /// destroyed w/o their being able to unregister from it (which can happen if
0329   /// the Broadcasters & Listeners are being destroyed on separate threads
0330   /// simultaneously. The Broadcaster itself can't be shared out as a weak
0331   /// pointer, because some things that are broadcasters (e.g. the Target and
0332   /// the Process) are shared in their own right.
0333   ///
0334   /// For the most part, the Broadcaster functions dispatch to the
0335   /// BroadcasterImpl, and are documented in the public Broadcaster API above.
0336   class BroadcasterImpl {
0337     friend class Listener;
0338     friend class Broadcaster;
0339 
0340   public:
0341     BroadcasterImpl(Broadcaster &broadcaster);
0342 
0343     ~BroadcasterImpl() = default;
0344 
0345     void BroadcastEvent(lldb::EventSP &event_sp);
0346 
0347     void BroadcastEventIfUnique(lldb::EventSP &event_sp);
0348 
0349     void BroadcastEvent(uint32_t event_type);
0350 
0351     void BroadcastEvent(uint32_t event_type,
0352                         const lldb::EventDataSP &event_data_sp);
0353 
0354     void BroadcastEventIfUnique(uint32_t event_type);
0355 
0356     void Clear();
0357 
0358     uint32_t AddListener(const lldb::ListenerSP &listener_sp,
0359                          uint32_t event_mask);
0360 
0361     const std::string &GetBroadcasterName() const {
0362       return m_broadcaster.GetBroadcasterName();
0363     }
0364 
0365     Broadcaster *GetBroadcaster();
0366 
0367     bool GetEventNames(Stream &s, const uint32_t event_mask,
0368                        bool prefix_with_broadcaster_name) const;
0369 
0370     void SetEventName(uint32_t event_mask, const char *name) {
0371       m_event_names[event_mask] = name;
0372     }
0373 
0374     const char *GetEventName(uint32_t event_mask) const {
0375       const auto pos = m_event_names.find(event_mask);
0376       if (pos != m_event_names.end())
0377         return pos->second.c_str();
0378       return nullptr;
0379     }
0380 
0381     bool EventTypeHasListeners(uint32_t event_type);
0382 
0383     void SetPrimaryListener(lldb::ListenerSP listener_sp);
0384 
0385     bool RemoveListener(lldb_private::Listener *listener,
0386                         uint32_t event_mask = UINT32_MAX);
0387 
0388     bool RemoveListener(const lldb::ListenerSP &listener_sp,
0389                         uint32_t event_mask = UINT32_MAX);
0390 
0391     bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
0392                            uint32_t event_mask = UINT32_MAX);
0393 
0394     bool IsHijackedForEvent(uint32_t event_mask);
0395 
0396     void RestoreBroadcaster();
0397 
0398   protected:
0399     void PrivateBroadcastEvent(lldb::EventSP &event_sp, bool unique);
0400 
0401     const char *GetHijackingListenerName();
0402 
0403     typedef llvm::SmallVector<std::pair<lldb::ListenerWP, uint32_t>, 4>
0404         collection;
0405     typedef std::map<uint32_t, std::string> event_names_map;
0406 
0407     llvm::SmallVector<std::pair<lldb::ListenerSP, uint32_t &>, 4>
0408     GetListeners(uint32_t event_mask = UINT32_MAX, bool include_primary = true);
0409 
0410     bool HasListeners(uint32_t event_mask);
0411 
0412     /// The broadcaster that this implements.
0413     Broadcaster &m_broadcaster;
0414 
0415     /// Optionally define event names for readability and logging for each
0416     /// event bit.
0417     event_names_map m_event_names;
0418 
0419     /// A Broadcaster can have zero, one or many listeners.  A Broadcaster with
0420     /// zero listeners is a no-op, with one Listener is trivial.
0421     /// In most cases of multiple Listeners,the Broadcaster treats all its
0422     /// Listeners as equal, sending each event to all of the Listeners in no
0423     /// guaranteed order.
0424     /// However, some Broadcasters - in particular the Process broadcaster, can
0425     /// designate one Listener to be the "Primary Listener".  In the case of
0426     /// the Process Broadcaster, the Listener passed to the Process constructor
0427     /// will be the Primary Listener.
0428     /// If the broadcaster has a Primary Listener, then the event gets
0429     /// sent first to the Primary Listener, and then when the Primary Listener
0430     /// pulls the event and the the event's DoOnRemoval finishes running,
0431     /// the event is forwarded to all the other Listeners.
0432     /// The other wrinkle is that a Broadcaster may be serving a Hijack
0433     /// Listener.  If the Hijack Listener is present, events are only sent to
0434     /// the Hijack Listener.  We use that, for instance, to absorb all the
0435     /// events generated by running an expression so that they don't show up to
0436     /// the driver or UI as starts and stops.
0437     /// If a Broadcaster has both a Primary and a Hijack Listener, the top-most
0438     /// Hijack Listener is treated as the current Primary Listener.
0439 
0440     /// A list of Listener / event_mask pairs that are listening to this
0441     /// broadcaster.
0442     collection m_listeners;
0443 
0444     /// A mutex that protects \a m_listeners.
0445     std::mutex m_listeners_mutex;
0446 
0447     /// See the discussion of Broadcasters and Listeners above.
0448     lldb::ListenerSP m_primary_listener_sp;
0449     // The primary listener listens to all bits:
0450     uint32_t m_primary_listener_mask = UINT32_MAX;
0451 
0452     /// A simple mechanism to intercept events from a broadcaster
0453     std::vector<lldb::ListenerSP> m_hijacking_listeners;
0454 
0455     /// At some point we may want to have a stack or Listener collections, but
0456     /// for now this is just for private hijacking.
0457     std::vector<uint32_t> m_hijacking_masks;
0458 
0459   private:
0460     BroadcasterImpl(const BroadcasterImpl &) = delete;
0461     const BroadcasterImpl &operator=(const BroadcasterImpl &) = delete;
0462   };
0463 
0464   typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP;
0465   typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP;
0466 
0467   BroadcasterImplSP GetBroadcasterImpl() { return m_broadcaster_sp; }
0468 
0469   const char *GetHijackingListenerName() {
0470     return m_broadcaster_sp->GetHijackingListenerName();
0471   }
0472 
0473 private:
0474   BroadcasterImplSP m_broadcaster_sp;
0475   lldb::BroadcasterManagerSP m_manager_sp;
0476 
0477   /// The name of this broadcaster object.
0478   const std::string m_broadcaster_name;
0479 
0480   Broadcaster(const Broadcaster &) = delete;
0481   const Broadcaster &operator=(const Broadcaster &) = delete;
0482 };
0483 
0484 } // namespace lldb_private
0485 
0486 #endif // LLDB_UTILITY_BROADCASTER_H