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(ConstString broadcaster_class,uint32_t event_bits)42 BroadcastEventSpec(ConstString broadcaster_class, uint32_t event_bits) 43 : m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {} 44 45 ~BroadcastEventSpec() = default; 46 GetBroadcasterClass()47 ConstString 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 ConstString 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 uint32_t RegisterListenerForEvents(const lldb::ListenerSP &listener_sp, 91 const BroadcastEventSpec &event_spec); 92 93 bool UnregisterListenerForEvents(const lldb::ListenerSP &listener_sp, 94 const BroadcastEventSpec &event_spec); 95 96 lldb::ListenerSP 97 GetListenerForEventSpec(const BroadcastEventSpec &event_spec) const; 98 99 void SignUpListenersForBroadcaster(Broadcaster &broadcaster); 100 101 void RemoveListener(const lldb::ListenerSP &listener_sp); 102 103 void RemoveListener(Listener *listener); 104 105 void Clear(); 106 107 private: 108 typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key; 109 typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection; 110 typedef std::set<lldb::ListenerSP> listener_collection; 111 collection m_event_map; 112 listener_collection m_listeners; 113 114 mutable std::recursive_mutex m_manager_mutex; 115 116 // A couple of comparator classes for find_if: 117 118 class BroadcasterClassMatches { 119 public: BroadcasterClassMatches(ConstString broadcaster_class)120 BroadcasterClassMatches(ConstString broadcaster_class) 121 : m_broadcaster_class(broadcaster_class) {} 122 123 ~BroadcasterClassMatches() = default; 124 operator()125 bool operator()(const event_listener_key &input) const { 126 return (input.first.GetBroadcasterClass() == m_broadcaster_class); 127 } 128 129 private: 130 ConstString m_broadcaster_class; 131 }; 132 133 class BroadcastEventSpecMatches { 134 public: BroadcastEventSpecMatches(const BroadcastEventSpec & broadcaster_spec)135 BroadcastEventSpecMatches(const BroadcastEventSpec &broadcaster_spec) 136 : m_broadcaster_spec(broadcaster_spec) {} 137 138 ~BroadcastEventSpecMatches() = default; 139 operator()140 bool operator()(const event_listener_key &input) const { 141 return (input.first.IsContainedIn(m_broadcaster_spec)); 142 } 143 144 private: 145 BroadcastEventSpec m_broadcaster_spec; 146 }; 147 148 class ListenerMatchesAndSharedBits { 149 public: ListenerMatchesAndSharedBits(const BroadcastEventSpec & broadcaster_spec,const lldb::ListenerSP & listener_sp)150 explicit ListenerMatchesAndSharedBits( 151 const BroadcastEventSpec &broadcaster_spec, 152 const lldb::ListenerSP &listener_sp) 153 : m_broadcaster_spec(broadcaster_spec), m_listener_sp(listener_sp) {} 154 155 ~ListenerMatchesAndSharedBits() = default; 156 operator()157 bool operator()(const event_listener_key &input) const { 158 return (input.first.GetBroadcasterClass() == 159 m_broadcaster_spec.GetBroadcasterClass() && 160 (input.first.GetEventBits() & 161 m_broadcaster_spec.GetEventBits()) != 0 && 162 input.second == m_listener_sp); 163 } 164 165 private: 166 BroadcastEventSpec m_broadcaster_spec; 167 const lldb::ListenerSP m_listener_sp; 168 }; 169 170 class ListenerMatches { 171 public: ListenerMatches(const lldb::ListenerSP & in_listener_sp)172 explicit ListenerMatches(const lldb::ListenerSP &in_listener_sp) 173 : m_listener_sp(in_listener_sp) {} 174 175 ~ListenerMatches() = default; 176 operator()177 bool operator()(const event_listener_key &input) const { 178 if (input.second == m_listener_sp) 179 return true; 180 181 return false; 182 } 183 184 private: 185 const lldb::ListenerSP m_listener_sp; 186 }; 187 188 class ListenerMatchesPointer { 189 public: ListenerMatchesPointer(const Listener * in_listener)190 ListenerMatchesPointer(const Listener *in_listener) 191 : m_listener(in_listener) {} 192 193 ~ListenerMatchesPointer() = default; 194 operator()195 bool operator()(const event_listener_key &input) const { 196 if (input.second.get() == m_listener) 197 return true; 198 199 return false; 200 } 201 operator()202 bool operator()(const lldb::ListenerSP &input) const { 203 if (input.get() == m_listener) 204 return true; 205 206 return false; 207 } 208 209 private: 210 const Listener *m_listener; 211 }; 212 }; 213 214 /// \class Broadcaster Broadcaster.h "lldb/Utility/Broadcaster.h" An event 215 /// broadcasting class. 216 /// 217 /// The Broadcaster class is designed to be subclassed by objects that wish to 218 /// vend events in a multi-threaded environment. Broadcaster objects can each 219 /// vend 32 events. Each event is represented by a bit in a 32 bit value and 220 /// these bits can be set: 221 /// \see Broadcaster::SetEventBits(uint32_t) 222 /// or cleared: 223 /// \see Broadcaster::ResetEventBits(uint32_t) 224 /// When an event gets set the Broadcaster object will notify the Listener 225 /// object that is listening for the event (if there is one). 226 /// 227 /// Subclasses should provide broadcast bit definitions for any events they 228 /// vend, typically using an enumeration: 229 /// \code 230 /// class Foo : public Broadcaster 231 /// { 232 /// public: 233 /// // Broadcaster event bits definitions. 234 /// enum 235 /// { 236 /// eBroadcastBitOne = (1 << 0), 237 /// eBroadcastBitTwo = (1 << 1), 238 /// eBroadcastBitThree = (1 << 2), 239 /// ... 240 /// }; 241 /// \endcode 242 class Broadcaster { 243 friend class Listener; 244 friend class Event; 245 246 public: 247 /// Construct with a broadcaster with a name. 248 /// 249 /// \param[in] name 250 /// A NULL terminated C string that contains the name of the 251 /// broadcaster object. 252 Broadcaster(lldb::BroadcasterManagerSP manager_sp, const char *name); 253 254 /// Destructor. 255 /// 256 /// The destructor is virtual since this class gets subclassed. 257 virtual ~Broadcaster(); 258 259 void CheckInWithManager(); 260 261 /// Broadcast an event which has no associated data. 262 /// 263 /// \param[in] event_type 264 /// The element from the enum defining this broadcaster's events 265 /// that is being broadcast. 266 /// 267 /// \param[in] event_data 268 /// User event data that will be owned by the lldb::Event that 269 /// is created internally. 270 /// 271 /// \param[in] unique 272 /// If true, then only add an event of this type if there isn't 273 /// one already in the queue. 274 /// BroadcastEvent(lldb::EventSP & event_sp)275 void BroadcastEvent(lldb::EventSP &event_sp) { 276 m_broadcaster_sp->BroadcastEvent(event_sp); 277 } 278 BroadcastEventIfUnique(lldb::EventSP & event_sp)279 void BroadcastEventIfUnique(lldb::EventSP &event_sp) { 280 m_broadcaster_sp->BroadcastEventIfUnique(event_sp); 281 } 282 BroadcastEvent(uint32_t event_type,const lldb::EventDataSP & event_data_sp)283 void BroadcastEvent(uint32_t event_type, 284 const lldb::EventDataSP &event_data_sp) { 285 m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp); 286 } 287 288 void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr) { 289 m_broadcaster_sp->BroadcastEvent(event_type, event_data); 290 } 291 292 void BroadcastEventIfUnique(uint32_t event_type, 293 EventData *event_data = nullptr) { 294 m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data); 295 } 296 Clear()297 void Clear() { m_broadcaster_sp->Clear(); } 298 299 virtual void AddInitialEventsToListener(const lldb::ListenerSP &listener_sp, 300 uint32_t requested_events); 301 302 /// Listen for any events specified by \a event_mask. 303 /// 304 /// Only one listener can listen to each event bit in a given Broadcaster. 305 /// Once a listener has acquired an event bit, no other broadcaster will 306 /// have access to it until it is relinquished by the first listener that 307 /// gets it. The actual event bits that get acquired by \a listener may be 308 /// different from what is requested in \a event_mask, and to track this the 309 /// actual event bits that are acquired get returned. 310 /// 311 /// \param[in] listener 312 /// The Listener object that wants to monitor the events that 313 /// get broadcast by this object. 314 /// 315 /// \param[in] event_mask 316 /// A bit mask that indicates which events the listener is 317 /// asking to monitor. 318 /// 319 /// \return 320 /// The actual event bits that were acquired by \a listener. AddListener(const lldb::ListenerSP & listener_sp,uint32_t event_mask)321 uint32_t AddListener(const lldb::ListenerSP &listener_sp, 322 uint32_t event_mask) { 323 return m_broadcaster_sp->AddListener(listener_sp, event_mask); 324 } 325 326 /// Get the NULL terminated C string name of this Broadcaster object. 327 /// 328 /// \return 329 /// The NULL terminated C string name of this Broadcaster. GetBroadcasterName()330 ConstString GetBroadcasterName() { return m_broadcaster_name; } 331 332 /// Get the event name(s) for one or more event bits. 333 /// 334 /// \param[in] event_mask 335 /// A bit mask that indicates which events to get names for. 336 /// 337 /// \return 338 /// The NULL terminated C string name of this Broadcaster. GetEventNames(Stream & s,const uint32_t event_mask,bool prefix_with_broadcaster_name)339 bool GetEventNames(Stream &s, const uint32_t event_mask, 340 bool prefix_with_broadcaster_name) const { 341 return m_broadcaster_sp->GetEventNames(s, event_mask, 342 prefix_with_broadcaster_name); 343 } 344 345 /// Set the name for an event bit. 346 /// 347 /// \param[in] event_mask 348 /// A bit mask that indicates which events the listener is 349 /// asking to monitor. 350 /// 351 /// \return 352 /// The NULL terminated C string name of this Broadcaster. SetEventName(uint32_t event_mask,const char * name)353 void SetEventName(uint32_t event_mask, const char *name) { 354 m_broadcaster_sp->SetEventName(event_mask, name); 355 } 356 GetEventName(uint32_t event_mask)357 const char *GetEventName(uint32_t event_mask) const { 358 return m_broadcaster_sp->GetEventName(event_mask); 359 } 360 EventTypeHasListeners(uint32_t event_type)361 bool EventTypeHasListeners(uint32_t event_type) { 362 return m_broadcaster_sp->EventTypeHasListeners(event_type); 363 } 364 365 /// Removes a Listener from this broadcasters list and frees the event bits 366 /// specified by \a event_mask that were previously acquired by \a listener 367 /// (assuming \a listener was listening to this object) for other listener 368 /// objects to use. 369 /// 370 /// \param[in] listener 371 /// A Listener object that previously called AddListener. 372 /// 373 /// \param[in] event_mask 374 /// The event bits \a listener wishes to relinquish. 375 /// 376 /// \return 377 /// \b True if the listener was listening to this broadcaster 378 /// and was removed, \b false otherwise. 379 /// 380 /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t) 381 bool RemoveListener(const lldb::ListenerSP &listener_sp, 382 uint32_t event_mask = UINT32_MAX) { 383 return m_broadcaster_sp->RemoveListener(listener_sp, event_mask); 384 } 385 386 /// Provides a simple mechanism to temporarily redirect events from 387 /// broadcaster. When you call this function passing in a listener and 388 /// event type mask, all events from the broadcaster matching the mask will 389 /// now go to the hijacking listener. Only one hijack can occur at a time. 390 /// If we need more than this we will have to implement a Listener stack. 391 /// 392 /// \param[in] listener 393 /// A Listener object. You do not need to call StartListeningForEvents 394 /// for this broadcaster (that would fail anyway since the event bits 395 /// would most likely be taken by the listener(s) you are usurping. 396 /// 397 /// \param[in] event_mask 398 /// The event bits \a listener wishes to hijack. 399 /// 400 /// \return 401 /// \b True if the event mask could be hijacked, \b false otherwise. 402 /// 403 /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t) 404 bool HijackBroadcaster(const lldb::ListenerSP &listener_sp, 405 uint32_t event_mask = UINT32_MAX) { 406 return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask); 407 } 408 IsHijackedForEvent(uint32_t event_mask)409 bool IsHijackedForEvent(uint32_t event_mask) { 410 return m_broadcaster_sp->IsHijackedForEvent(event_mask); 411 } 412 413 /// Restore the state of the Broadcaster from a previous hijack attempt. RestoreBroadcaster()414 void RestoreBroadcaster() { m_broadcaster_sp->RestoreBroadcaster(); } 415 416 /// This needs to be filled in if you are going to register the broadcaster 417 /// with the broadcaster manager and do broadcaster class matching. 418 /// FIXME: Probably should make a ManagedBroadcaster subclass with all the 419 /// bits needed to work with the BroadcasterManager, so that it is clearer 420 /// how to add one. 421 virtual ConstString &GetBroadcasterClass() const; 422 423 lldb::BroadcasterManagerSP GetManager(); 424 425 protected: 426 /// BroadcasterImpl contains the actual Broadcaster implementation. The 427 /// Broadcaster makes a BroadcasterImpl which lives as long as it does. The 428 /// Listeners & the Events hold a weak pointer to the BroadcasterImpl, so 429 /// that they can survive if a Broadcaster they were listening to is 430 /// destroyed w/o their being able to unregister from it (which can happen if 431 /// the Broadcasters & Listeners are being destroyed on separate threads 432 /// simultaneously. The Broadcaster itself can't be shared out as a weak 433 /// pointer, because some things that are broadcasters (e.g. the Target and 434 /// the Process) are shared in their own right. 435 /// 436 /// For the most part, the Broadcaster functions dispatch to the 437 /// BroadcasterImpl, and are documented in the public Broadcaster API above. 438 class BroadcasterImpl { 439 friend class Listener; 440 friend class Broadcaster; 441 442 public: 443 BroadcasterImpl(Broadcaster &broadcaster); 444 445 ~BroadcasterImpl() = default; 446 447 void BroadcastEvent(lldb::EventSP &event_sp); 448 449 void BroadcastEventIfUnique(lldb::EventSP &event_sp); 450 451 void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr); 452 453 void BroadcastEvent(uint32_t event_type, 454 const lldb::EventDataSP &event_data_sp); 455 456 void BroadcastEventIfUnique(uint32_t event_type, 457 EventData *event_data = nullptr); 458 459 void Clear(); 460 461 uint32_t AddListener(const lldb::ListenerSP &listener_sp, 462 uint32_t event_mask); 463 GetBroadcasterName()464 const char *GetBroadcasterName() const { 465 return m_broadcaster.GetBroadcasterName().AsCString(); 466 } 467 468 Broadcaster *GetBroadcaster(); 469 470 bool GetEventNames(Stream &s, const uint32_t event_mask, 471 bool prefix_with_broadcaster_name) const; 472 SetEventName(uint32_t event_mask,const char * name)473 void SetEventName(uint32_t event_mask, const char *name) { 474 m_event_names[event_mask] = name; 475 } 476 GetEventName(uint32_t event_mask)477 const char *GetEventName(uint32_t event_mask) const { 478 const auto pos = m_event_names.find(event_mask); 479 if (pos != m_event_names.end()) 480 return pos->second.c_str(); 481 return nullptr; 482 } 483 484 bool EventTypeHasListeners(uint32_t event_type); 485 486 bool RemoveListener(lldb_private::Listener *listener, 487 uint32_t event_mask = UINT32_MAX); 488 489 bool RemoveListener(const lldb::ListenerSP &listener_sp, 490 uint32_t event_mask = UINT32_MAX); 491 492 bool HijackBroadcaster(const lldb::ListenerSP &listener_sp, 493 uint32_t event_mask = UINT32_MAX); 494 495 bool IsHijackedForEvent(uint32_t event_mask); 496 497 void RestoreBroadcaster(); 498 499 protected: 500 void PrivateBroadcastEvent(lldb::EventSP &event_sp, bool unique); 501 502 const char *GetHijackingListenerName(); 503 504 typedef llvm::SmallVector<std::pair<lldb::ListenerWP, uint32_t>, 4> 505 collection; 506 typedef std::map<uint32_t, std::string> event_names_map; 507 508 llvm::SmallVector<std::pair<lldb::ListenerSP, uint32_t &>, 4> 509 GetListeners(); 510 511 /// The broadcaster that this implements. 512 Broadcaster &m_broadcaster; 513 514 /// Optionally define event names for readability and logging for each 515 /// event bit. 516 event_names_map m_event_names; 517 518 /// A list of Listener / event_mask pairs that are listening to this 519 /// broadcaster. 520 collection m_listeners; 521 522 /// A mutex that protects \a m_listeners. 523 std::recursive_mutex m_listeners_mutex; 524 525 /// A simple mechanism to intercept events from a broadcaster 526 std::vector<lldb::ListenerSP> m_hijacking_listeners; 527 528 /// At some point we may want to have a stack or Listener collections, but 529 /// for now this is just for private hijacking. 530 std::vector<uint32_t> m_hijacking_masks; 531 532 private: 533 DISALLOW_COPY_AND_ASSIGN(BroadcasterImpl); 534 }; 535 536 typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP; 537 typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP; 538 GetBroadcasterImpl()539 BroadcasterImplSP GetBroadcasterImpl() { return m_broadcaster_sp; } 540 GetHijackingListenerName()541 const char *GetHijackingListenerName() { 542 return m_broadcaster_sp->GetHijackingListenerName(); 543 } 544 545 private: 546 BroadcasterImplSP m_broadcaster_sp; 547 lldb::BroadcasterManagerSP m_manager_sp; 548 549 /// The name of this broadcaster object. 550 const ConstString m_broadcaster_name; 551 552 DISALLOW_COPY_AND_ASSIGN(Broadcaster); 553 }; 554 555 } // namespace lldb_private 556 557 #endif // LLDB_UTILITY_BROADCASTER_H 558