Broadcaster.h 18 KB

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