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