1 //===-- Broadcaster.h -------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_UTILITY_BROADCASTER_H 10 #define LLDB_UTILITY_BROADCASTER_H 11 12 #include "lldb/Utility/ConstString.h" 13 #include "lldb/lldb-defines.h" 14 #include "lldb/lldb-forward.h" 15 16 #include "llvm/ADT/SmallVector.h" 17 18 #include <cstdint> 19 #include <map> 20 #include <memory> 21 #include <mutex> 22 #include <set> 23 #include <string> 24 #include <utility> 25 #include <vector> 26 27 namespace lldb_private { 28 class Broadcaster; 29 class EventData; 30 class Listener; 31 class Stream; 32 } // namespace lldb_private 33 34 namespace lldb_private { 35 36 /// lldb::BroadcastEventSpec 37 /// 38 /// This class is used to specify a kind of event to register for. The 39 /// Debugger maintains a list of BroadcastEventSpec's and when it is made 40 class BroadcastEventSpec { 41 public: BroadcastEventSpec(llvm::StringRef broadcaster_class,uint32_t event_bits)42 BroadcastEventSpec(llvm::StringRef broadcaster_class, uint32_t event_bits) 43 : m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {} 44 45 ~BroadcastEventSpec() = default; 46 GetBroadcasterClass()47 const std::string &GetBroadcasterClass() const { return m_broadcaster_class; } 48 GetEventBits()49 uint32_t GetEventBits() const { return m_event_bits; } 50 51 /// Tell whether this BroadcastEventSpec is contained in in_spec. That is: 52 /// (a) the two spec's share the same broadcaster class (b) the event bits of 53 /// this spec are wholly contained in those of in_spec. IsContainedIn(const BroadcastEventSpec & in_spec)54 bool IsContainedIn(const BroadcastEventSpec &in_spec) const { 55 if (m_broadcaster_class != in_spec.GetBroadcasterClass()) 56 return false; 57 uint32_t in_bits = in_spec.GetEventBits(); 58 if (in_bits == m_event_bits) 59 return true; 60 61 if ((m_event_bits & in_bits) != 0 && (m_event_bits & ~in_bits) == 0) 62 return true; 63 64 return false; 65 } 66 67 bool operator<(const BroadcastEventSpec &rhs) const; 68 69 private: 70 std::string m_broadcaster_class; 71 uint32_t m_event_bits; 72 }; 73 74 class BroadcasterManager 75 : public std::enable_shared_from_this<BroadcasterManager> { 76 public: 77 friend class Listener; 78 79 protected: 80 BroadcasterManager(); 81 82 public: 83 /// Listeners hold onto weak pointers to their broadcaster managers. So they 84 /// must be made into shared pointers, which you do with 85 /// MakeBroadcasterManager. 86 static lldb::BroadcasterManagerSP MakeBroadcasterManager(); 87 88 ~BroadcasterManager() = default; 89 90 lldb::ListenerSP 91 GetListenerForEventSpec(const BroadcastEventSpec &event_spec) const; 92 93 void SignUpListenersForBroadcaster(Broadcaster &broadcaster); 94 95 void RemoveListener(const lldb::ListenerSP &listener_sp); 96 97 void RemoveListener(Listener *listener); 98 99 void Clear(); 100 101 private: 102 uint32_t 103 RegisterListenerForEventsNoLock(const lldb::ListenerSP &listener_sp, 104 const BroadcastEventSpec &event_spec); 105 106 bool UnregisterListenerForEventsNoLock(const lldb::ListenerSP &listener_sp, 107 const BroadcastEventSpec &event_spec); 108 109 typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key; 110 typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection; 111 typedef std::set<lldb::ListenerSP> listener_collection; 112 collection m_event_map; 113 listener_collection m_listeners; 114 115 mutable std::mutex m_manager_mutex; 116 }; 117 118 /// \class Broadcaster Broadcaster.h "lldb/Utility/Broadcaster.h" An event 119 /// broadcasting class. 120 /// 121 /// The Broadcaster class is designed to be subclassed by objects that wish to 122 /// vend events in a multi-threaded environment. Broadcaster objects can each 123 /// vend 32 events. Each event is represented by a bit in a 32 bit value and 124 /// these bits can be set: 125 /// \see Broadcaster::SetEventBits(uint32_t) 126 /// or cleared: 127 /// \see Broadcaster::ResetEventBits(uint32_t) 128 /// When an event gets set the Broadcaster object will notify the Listener 129 /// object that is listening for the event (if there is one). 130 /// 131 /// Subclasses should provide broadcast bit definitions for any events they 132 /// vend, typically using an enumeration: 133 /// \code 134 /// class Foo : public Broadcaster 135 /// { 136 /// public: 137 /// // Broadcaster event bits definitions. 138 /// enum 139 /// { 140 /// eBroadcastBitOne = (1 << 0), 141 /// eBroadcastBitTwo = (1 << 1), 142 /// eBroadcastBitThree = (1 << 2), 143 /// ... 144 /// }; 145 /// \endcode 146 class Broadcaster { 147 friend class Listener; 148 friend class Event; 149 150 public: 151 /// Construct with a broadcaster with a name. 152 /// 153 /// \param[in] manager_sp 154 /// A shared pointer to the BroadcasterManager that will manage this 155 /// broadcaster. 156 /// \param[in] name 157 /// A std::string of the name that this broadcaster will have. 158 Broadcaster(lldb::BroadcasterManagerSP manager_sp, std::string name); 159 160 /// Destructor. 161 /// 162 /// The destructor is virtual since this class gets subclassed. 163 virtual ~Broadcaster(); 164 165 void CheckInWithManager(); 166 167 /// Broadcast an event which has no associated data. BroadcastEvent(lldb::EventSP & event_sp)168 void BroadcastEvent(lldb::EventSP &event_sp) { 169 m_broadcaster_sp->BroadcastEvent(event_sp); 170 } 171 BroadcastEventIfUnique(lldb::EventSP & event_sp)172 void BroadcastEventIfUnique(lldb::EventSP &event_sp) { 173 m_broadcaster_sp->BroadcastEventIfUnique(event_sp); 174 } 175 BroadcastEvent(uint32_t event_type,const lldb::EventDataSP & event_data_sp)176 void BroadcastEvent(uint32_t event_type, 177 const lldb::EventDataSP &event_data_sp) { 178 m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp); 179 } 180 BroadcastEvent(uint32_t event_type)181 void BroadcastEvent(uint32_t event_type) { 182 m_broadcaster_sp->BroadcastEvent(event_type); 183 } 184 BroadcastEventIfUnique(uint32_t event_type)185 void BroadcastEventIfUnique(uint32_t event_type) { 186 m_broadcaster_sp->BroadcastEventIfUnique(event_type); 187 } 188 Clear()189 void Clear() { m_broadcaster_sp->Clear(); } 190 191 virtual void AddInitialEventsToListener(const lldb::ListenerSP &listener_sp, 192 uint32_t requested_events); 193 194 /// Listen for any events specified by \a event_mask. 195 /// 196 /// Only one listener can listen to each event bit in a given Broadcaster. 197 /// Once a listener has acquired an event bit, no other broadcaster will 198 /// have access to it until it is relinquished by the first listener that 199 /// gets it. The actual event bits that get acquired by \a listener may be 200 /// different from what is requested in \a event_mask, and to track this the 201 /// actual event bits that are acquired get returned. 202 /// 203 /// \param[in] listener_sp 204 /// The Listener object that wants to monitor the events that 205 /// get broadcast by this object. 206 /// 207 /// \param[in] event_mask 208 /// A bit mask that indicates which events the listener is 209 /// asking to monitor. 210 /// 211 /// \return 212 /// The actual event bits that were acquired by \a listener. AddListener(const lldb::ListenerSP & listener_sp,uint32_t event_mask)213 uint32_t AddListener(const lldb::ListenerSP &listener_sp, 214 uint32_t event_mask) { 215 return m_broadcaster_sp->AddListener(listener_sp, event_mask); 216 } 217 218 /// Get this broadcaster's name. 219 /// 220 /// \return 221 /// A reference to a constant std::string containing the name of the 222 /// broadcaster. GetBroadcasterName()223 const std::string &GetBroadcasterName() { return m_broadcaster_name; } 224 225 /// Get the event name(s) for one or more event bits. 226 /// 227 /// \param[in] event_mask 228 /// A bit mask that indicates which events to get names for. 229 /// 230 /// \return 231 /// The NULL terminated C string name of this Broadcaster. GetEventNames(Stream & s,const uint32_t event_mask,bool prefix_with_broadcaster_name)232 bool GetEventNames(Stream &s, const uint32_t event_mask, 233 bool prefix_with_broadcaster_name) const { 234 return m_broadcaster_sp->GetEventNames(s, event_mask, 235 prefix_with_broadcaster_name); 236 } 237 238 /// Set the name for an event bit. 239 /// 240 /// \param[in] event_mask 241 /// A bit mask that indicates which events the listener is 242 /// asking to monitor. SetEventName(uint32_t event_mask,const char * name)243 void SetEventName(uint32_t event_mask, const char *name) { 244 m_broadcaster_sp->SetEventName(event_mask, name); 245 } 246 GetEventName(uint32_t event_mask)247 const char *GetEventName(uint32_t event_mask) const { 248 return m_broadcaster_sp->GetEventName(event_mask); 249 } 250 EventTypeHasListeners(uint32_t event_type)251 bool EventTypeHasListeners(uint32_t event_type) { 252 return m_broadcaster_sp->EventTypeHasListeners(event_type); 253 } 254 255 /// Removes a Listener from this broadcasters list and frees the event bits 256 /// specified by \a event_mask that were previously acquired by \a listener 257 /// (assuming \a listener was listening to this object) for other listener 258 /// objects to use. 259 /// 260 /// \param[in] listener_sp 261 /// A Listener object that previously called AddListener. 262 /// 263 /// \param[in] event_mask 264 /// The event bits \a listener wishes to relinquish. 265 /// 266 /// \return 267 /// \b True if the listener was listening to this broadcaster 268 /// and was removed, \b false otherwise. 269 /// 270 /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t) 271 bool RemoveListener(const lldb::ListenerSP &listener_sp, 272 uint32_t event_mask = UINT32_MAX) { 273 return m_broadcaster_sp->RemoveListener(listener_sp, event_mask); 274 } 275 276 /// Provides a simple mechanism to temporarily redirect events from 277 /// broadcaster. When you call this function passing in a listener and 278 /// event type mask, all events from the broadcaster matching the mask will 279 /// now go to the hijacking listener. Only one hijack can occur at a time. 280 /// If we need more than this we will have to implement a Listener stack. 281 /// 282 /// \param[in] listener_sp 283 /// A Listener object. You do not need to call StartListeningForEvents 284 /// for this broadcaster (that would fail anyway since the event bits 285 /// would most likely be taken by the listener(s) you are usurping. 286 /// 287 /// \param[in] event_mask 288 /// The event bits \a listener wishes to hijack. 289 /// 290 /// \return 291 /// \b True if the event mask could be hijacked, \b false otherwise. 292 /// 293 /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t) 294 bool HijackBroadcaster(const lldb::ListenerSP &listener_sp, 295 uint32_t event_mask = UINT32_MAX) { 296 return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask); 297 } 298 IsHijackedForEvent(uint32_t event_mask)299 bool IsHijackedForEvent(uint32_t event_mask) { 300 return m_broadcaster_sp->IsHijackedForEvent(event_mask); 301 } 302 303 /// Restore the state of the Broadcaster from a previous hijack attempt. RestoreBroadcaster()304 void RestoreBroadcaster() { m_broadcaster_sp->RestoreBroadcaster(); } 305 306 /// This needs to be filled in if you are going to register the broadcaster 307 /// with the broadcaster manager and do broadcaster class matching. 308 /// FIXME: Probably should make a ManagedBroadcaster subclass with all the 309 /// bits needed to work with the BroadcasterManager, so that it is clearer 310 /// how to add one. 311 virtual llvm::StringRef GetBroadcasterClass() const; 312 313 lldb::BroadcasterManagerSP GetManager(); 314 SetPrimaryListener(lldb::ListenerSP listener_sp)315 void SetPrimaryListener(lldb::ListenerSP listener_sp) { 316 m_broadcaster_sp->SetPrimaryListener(listener_sp); 317 } 318 GetPrimaryListener()319 lldb::ListenerSP GetPrimaryListener() { 320 return m_broadcaster_sp->m_primary_listener_sp; 321 } 322 323 protected: 324 /// BroadcasterImpl contains the actual Broadcaster implementation. The 325 /// Broadcaster makes a BroadcasterImpl which lives as long as it does. The 326 /// Listeners & the Events hold a weak pointer to the BroadcasterImpl, so 327 /// that they can survive if a Broadcaster they were listening to is 328 /// destroyed w/o their being able to unregister from it (which can happen if 329 /// the Broadcasters & Listeners are being destroyed on separate threads 330 /// simultaneously. The Broadcaster itself can't be shared out as a weak 331 /// pointer, because some things that are broadcasters (e.g. the Target and 332 /// the Process) are shared in their own right. 333 /// 334 /// For the most part, the Broadcaster functions dispatch to the 335 /// BroadcasterImpl, and are documented in the public Broadcaster API above. 336 class BroadcasterImpl { 337 friend class Listener; 338 friend class Broadcaster; 339 340 public: 341 BroadcasterImpl(Broadcaster &broadcaster); 342 343 ~BroadcasterImpl() = default; 344 345 void BroadcastEvent(lldb::EventSP &event_sp); 346 347 void BroadcastEventIfUnique(lldb::EventSP &event_sp); 348 349 void BroadcastEvent(uint32_t event_type); 350 351 void BroadcastEvent(uint32_t event_type, 352 const lldb::EventDataSP &event_data_sp); 353 354 void BroadcastEventIfUnique(uint32_t event_type); 355 356 void Clear(); 357 358 uint32_t AddListener(const lldb::ListenerSP &listener_sp, 359 uint32_t event_mask); 360 GetBroadcasterName()361 const std::string &GetBroadcasterName() const { 362 return m_broadcaster.GetBroadcasterName(); 363 } 364 365 Broadcaster *GetBroadcaster(); 366 367 bool GetEventNames(Stream &s, const uint32_t event_mask, 368 bool prefix_with_broadcaster_name) const; 369 SetEventName(uint32_t event_mask,const char * name)370 void SetEventName(uint32_t event_mask, const char *name) { 371 m_event_names[event_mask] = name; 372 } 373 GetEventName(uint32_t event_mask)374 const char *GetEventName(uint32_t event_mask) const { 375 const auto pos = m_event_names.find(event_mask); 376 if (pos != m_event_names.end()) 377 return pos->second.c_str(); 378 return nullptr; 379 } 380 381 bool EventTypeHasListeners(uint32_t event_type); 382 383 void SetPrimaryListener(lldb::ListenerSP listener_sp); 384 385 bool RemoveListener(lldb_private::Listener *listener, 386 uint32_t event_mask = UINT32_MAX); 387 388 bool RemoveListener(const lldb::ListenerSP &listener_sp, 389 uint32_t event_mask = UINT32_MAX); 390 391 bool HijackBroadcaster(const lldb::ListenerSP &listener_sp, 392 uint32_t event_mask = UINT32_MAX); 393 394 bool IsHijackedForEvent(uint32_t event_mask); 395 396 void RestoreBroadcaster(); 397 398 protected: 399 void PrivateBroadcastEvent(lldb::EventSP &event_sp, bool unique); 400 401 const char *GetHijackingListenerName(); 402 403 typedef llvm::SmallVector<std::pair<lldb::ListenerWP, uint32_t>, 4> 404 collection; 405 typedef std::map<uint32_t, std::string> event_names_map; 406 407 llvm::SmallVector<std::pair<lldb::ListenerSP, uint32_t &>, 4> 408 GetListeners(uint32_t event_mask = UINT32_MAX, bool include_primary = true); 409 410 bool HasListeners(uint32_t event_mask); 411 412 /// The broadcaster that this implements. 413 Broadcaster &m_broadcaster; 414 415 /// Optionally define event names for readability and logging for each 416 /// event bit. 417 event_names_map m_event_names; 418 419 /// A Broadcaster can have zero, one or many listeners. A Broadcaster with 420 /// zero listeners is a no-op, with one Listener is trivial. 421 /// In most cases of multiple Listeners,the Broadcaster treats all its 422 /// Listeners as equal, sending each event to all of the Listeners in no 423 /// guaranteed order. 424 /// However, some Broadcasters - in particular the Process broadcaster, can 425 /// designate one Listener to be the "Primary Listener". In the case of 426 /// the Process Broadcaster, the Listener passed to the Process constructor 427 /// will be the Primary Listener. 428 /// If the broadcaster has a Primary Listener, then the event gets 429 /// sent first to the Primary Listener, and then when the Primary Listener 430 /// pulls the event and the the event's DoOnRemoval finishes running, 431 /// the event is forwarded to all the other Listeners. 432 /// The other wrinkle is that a Broadcaster may be serving a Hijack 433 /// Listener. If the Hijack Listener is present, events are only sent to 434 /// the Hijack Listener. We use that, for instance, to absorb all the 435 /// events generated by running an expression so that they don't show up to 436 /// the driver or UI as starts and stops. 437 /// If a Broadcaster has both a Primary and a Hijack Listener, the top-most 438 /// Hijack Listener is treated as the current Primary Listener. 439 440 /// A list of Listener / event_mask pairs that are listening to this 441 /// broadcaster. 442 collection m_listeners; 443 444 /// A mutex that protects \a m_listeners. 445 std::mutex m_listeners_mutex; 446 447 /// See the discussion of Broadcasters and Listeners above. 448 lldb::ListenerSP m_primary_listener_sp; 449 // The primary listener listens to all bits: 450 uint32_t m_primary_listener_mask = UINT32_MAX; 451 452 /// A simple mechanism to intercept events from a broadcaster 453 std::vector<lldb::ListenerSP> m_hijacking_listeners; 454 455 /// At some point we may want to have a stack or Listener collections, but 456 /// for now this is just for private hijacking. 457 std::vector<uint32_t> m_hijacking_masks; 458 459 private: 460 BroadcasterImpl(const BroadcasterImpl &) = delete; 461 const BroadcasterImpl &operator=(const BroadcasterImpl &) = delete; 462 }; 463 464 typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP; 465 typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP; 466 GetBroadcasterImpl()467 BroadcasterImplSP GetBroadcasterImpl() { return m_broadcaster_sp; } 468 GetHijackingListenerName()469 const char *GetHijackingListenerName() { 470 return m_broadcaster_sp->GetHijackingListenerName(); 471 } 472 473 private: 474 BroadcasterImplSP m_broadcaster_sp; 475 lldb::BroadcasterManagerSP m_manager_sp; 476 477 /// The name of this broadcaster object. 478 const std::string m_broadcaster_name; 479 480 Broadcaster(const Broadcaster &) = delete; 481 const Broadcaster &operator=(const Broadcaster &) = delete; 482 }; 483 484 } // namespace lldb_private 485 486 #endif // LLDB_UTILITY_BROADCASTER_H 487