1 //===-- Broadcaster.h -------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_Broadcaster_h_ 11 #define liblldb_Broadcaster_h_ 12 13 // C Includes 14 // C++ Includes 15 #include <map> 16 #include <string> 17 #include <vector> 18 19 // Other libraries and framework includes 20 // Project includes 21 #include "lldb/lldb-private.h" 22 //#include "lldb/Core/Flags.h" 23 #include "lldb/Core/ConstString.h" 24 #include "lldb/Core/Listener.h" 25 26 namespace lldb_private { 27 28 //---------------------------------------------------------------------- 29 // lldb::BroadcastEventSpec 30 // 31 // This class is used to specify a kind of event to register for. The Debugger 32 // maintains a list of BroadcastEventSpec's and when it is made 33 //---------------------------------------------------------------------- 34 class BroadcastEventSpec 35 { 36 public: BroadcastEventSpec(const ConstString & broadcaster_class,uint32_t event_bits)37 BroadcastEventSpec (const ConstString &broadcaster_class, uint32_t event_bits) : 38 m_broadcaster_class (broadcaster_class), 39 m_event_bits (event_bits) 40 { 41 } 42 43 BroadcastEventSpec (const BroadcastEventSpec &rhs); 44 ~BroadcastEventSpec()45 ~BroadcastEventSpec() {} 46 GetBroadcasterClass()47 const ConstString &GetBroadcasterClass() const 48 { 49 return m_broadcaster_class; 50 } 51 GetEventBits()52 uint32_t GetEventBits () const 53 { 54 return m_event_bits; 55 } 56 57 // Tell whether this BroadcastEventSpec is contained in in_spec. 58 // That is: 59 // (a) the two spec's share the same broadcaster class 60 // (b) the event bits of this spec are wholly contained in those of in_spec. IsContainedIn(BroadcastEventSpec in_spec)61 bool IsContainedIn (BroadcastEventSpec in_spec) const 62 { 63 if (m_broadcaster_class != in_spec.GetBroadcasterClass()) 64 return false; 65 uint32_t in_bits = in_spec.GetEventBits(); 66 if (in_bits == m_event_bits) 67 return true; 68 else 69 { 70 if ((m_event_bits & in_bits) != 0 71 && (m_event_bits & ~in_bits) == 0) 72 return true; 73 } 74 return false; 75 } 76 77 bool operator< (const BroadcastEventSpec &rhs) const; 78 const BroadcastEventSpec &operator= (const BroadcastEventSpec &rhs); 79 80 private: 81 ConstString m_broadcaster_class; 82 uint32_t m_event_bits; 83 }; 84 85 class BroadcasterManager 86 { 87 public: 88 friend class Listener; 89 90 BroadcasterManager (); 91 ~BroadcasterManager()92 ~BroadcasterManager () {} 93 94 uint32_t 95 RegisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec); 96 97 bool 98 UnregisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec); 99 100 Listener * 101 GetListenerForEventSpec (BroadcastEventSpec event_spec) const; 102 103 void 104 SignUpListenersForBroadcaster (Broadcaster &broadcaster); 105 106 void 107 RemoveListener (Listener &Listener); 108 109 protected: 110 void Clear(); 111 112 private: 113 typedef std::pair<BroadcastEventSpec, Listener *> event_listener_key; 114 typedef std::map<BroadcastEventSpec, Listener *> collection; 115 typedef std::set<Listener *> listener_collection; 116 collection m_event_map; 117 listener_collection m_listeners; 118 119 Mutex m_manager_mutex; 120 121 // A couple of comparator classes for find_if: 122 123 class BroadcasterClassMatches 124 { 125 public: BroadcasterClassMatches(const ConstString & broadcaster_class)126 BroadcasterClassMatches (const ConstString &broadcaster_class) : 127 m_broadcaster_class (broadcaster_class) 128 { 129 } 130 ~BroadcasterClassMatches()131 ~BroadcasterClassMatches () {} 132 operator()133 bool operator() (const event_listener_key input) const 134 { 135 return (input.first.GetBroadcasterClass() == m_broadcaster_class); 136 } 137 138 private: 139 ConstString m_broadcaster_class; 140 }; 141 142 class BroadcastEventSpecMatches 143 { 144 public: BroadcastEventSpecMatches(BroadcastEventSpec broadcaster_spec)145 BroadcastEventSpecMatches (BroadcastEventSpec broadcaster_spec) : 146 m_broadcaster_spec (broadcaster_spec) 147 { 148 } 149 ~BroadcastEventSpecMatches()150 ~BroadcastEventSpecMatches () {} 151 operator()152 bool operator() (const event_listener_key input) const 153 { 154 return (input.first.IsContainedIn (m_broadcaster_spec)); 155 } 156 157 private: 158 BroadcastEventSpec m_broadcaster_spec; 159 }; 160 161 class ListenerMatchesAndSharedBits 162 { 163 public: ListenerMatchesAndSharedBits(BroadcastEventSpec broadcaster_spec,const Listener & listener)164 ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec, 165 const Listener &listener) : 166 m_broadcaster_spec (broadcaster_spec), 167 m_listener (&listener) 168 { 169 } 170 ~ListenerMatchesAndSharedBits()171 ~ListenerMatchesAndSharedBits () {} 172 operator()173 bool operator() (const event_listener_key input) const 174 { 175 return (input.first.GetBroadcasterClass() == m_broadcaster_spec.GetBroadcasterClass() 176 && (input.first.GetEventBits() & m_broadcaster_spec.GetEventBits()) != 0 177 && input.second == m_listener); 178 } 179 180 private: 181 BroadcastEventSpec m_broadcaster_spec; 182 const Listener *m_listener; 183 }; 184 185 class ListenerMatches 186 { 187 public: ListenerMatches(const Listener & in_listener)188 ListenerMatches (const Listener &in_listener) : 189 m_listener (&in_listener) 190 { 191 } 192 ~ListenerMatches()193 ~ListenerMatches() {} 194 operator()195 bool operator () (const event_listener_key input) const 196 { 197 if (input.second == m_listener) 198 return true; 199 else 200 return false; 201 } 202 203 private: 204 const Listener *m_listener; 205 206 }; 207 208 }; 209 210 //---------------------------------------------------------------------- 211 /// @class Broadcaster Broadcaster.h "lldb/Core/Broadcaster.h" 212 /// @brief An event broadcasting class. 213 /// 214 /// The Broadcaster class is designed to be subclassed by objects that 215 /// wish to vend events in a multi-threaded environment. Broadcaster 216 /// objects can each vend 32 events. Each event is represented by a bit 217 /// in a 32 bit value and these bits can be set: 218 /// @see Broadcaster::SetEventBits(uint32_t) 219 /// or cleared: 220 /// @see Broadcaster::ResetEventBits(uint32_t) 221 /// When an event gets set the Broadcaster object will notify the 222 /// Listener object that is listening for the event (if there is one). 223 /// 224 /// Subclasses should provide broadcast bit definitions for any events 225 /// they vend, typically using an enumeration: 226 /// \code 227 /// class Foo : public Broadcaster 228 /// { 229 /// public: 230 /// //---------------------------------------------------------- 231 /// // Broadcaster event bits definitions. 232 /// //---------------------------------------------------------- 233 /// enum 234 /// { 235 /// eBroadcastBitStateChanged = (1 << 0), 236 /// eBroadcastBitInterrupt = (1 << 1), 237 /// eBroadcastBitSTDOUT = (1 << 2), 238 /// eBroadcastBitSTDERR = (1 << 3), 239 /// eBroadcastBitProfileData = (1 << 4) 240 /// }; 241 /// \endcode 242 //---------------------------------------------------------------------- 243 class Broadcaster 244 { 245 public: 246 //------------------------------------------------------------------ 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 //------------------------------------------------------------------ 253 Broadcaster (BroadcasterManager *manager, const char *name); 254 255 //------------------------------------------------------------------ 256 /// Destructor. 257 /// 258 /// The destructor is virtual since this class gets subclassed. 259 //------------------------------------------------------------------ 260 virtual 261 ~Broadcaster(); 262 263 void 264 CheckInWithManager (); 265 266 //------------------------------------------------------------------ 267 /// Broadcast an event which has no associated data. 268 /// 269 /// @param[in] event_type 270 /// The element from the enum defining this broadcaster's events 271 /// that is being broadcast. 272 /// 273 /// @param[in] event_data 274 /// User event data that will be owned by the lldb::Event that 275 /// is created internally. 276 /// 277 /// @param[in] unique 278 /// If true, then only add an event of this type if there isn't 279 /// one already in the queue. 280 /// 281 //------------------------------------------------------------------ 282 void 283 BroadcastEvent (lldb::EventSP &event_sp); 284 285 void 286 BroadcastEventIfUnique (lldb::EventSP &event_sp); 287 288 void 289 BroadcastEvent (uint32_t event_type, EventData *event_data = NULL); 290 291 void 292 BroadcastEventIfUnique (uint32_t event_type, EventData *event_data = NULL); 293 294 void 295 Clear(); 296 297 virtual void 298 AddInitialEventsToListener (Listener *listener, uint32_t requested_events); 299 300 //------------------------------------------------------------------ 301 /// Listen for any events specified by \a event_mask. 302 /// 303 /// Only one listener can listen to each event bit in a given 304 /// Broadcaster. Once a listener has acquired an event bit, no 305 /// other broadcaster will have access to it until it is 306 /// relinquished by the first listener that gets it. The actual 307 /// event bits that get acquired by \a listener may be different 308 /// 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. 321 //------------------------------------------------------------------ 322 uint32_t 323 AddListener (Listener* listener, uint32_t event_mask); 324 325 //------------------------------------------------------------------ 326 /// Get the NULL terminated C string name of this Broadcaster 327 /// object. 328 /// 329 /// @return 330 /// The NULL terminated C string name of this Broadcaster. 331 //------------------------------------------------------------------ 332 const ConstString & 333 GetBroadcasterName (); 334 335 336 //------------------------------------------------------------------ 337 /// Get the event name(s) for one or more event bits. 338 /// 339 /// @param[in] event_mask 340 /// A bit mask that indicates which events to get names for. 341 /// 342 /// @return 343 /// The NULL terminated C string name of this Broadcaster. 344 //------------------------------------------------------------------ 345 bool 346 GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const; 347 348 //------------------------------------------------------------------ 349 /// Set the name for an event bit. 350 /// 351 /// @param[in] event_mask 352 /// A bit mask that indicates which events the listener is 353 /// asking to monitor. 354 /// 355 /// @return 356 /// The NULL terminated C string name of this Broadcaster. 357 //------------------------------------------------------------------ 358 void SetEventName(uint32_t event_mask,const char * name)359 SetEventName (uint32_t event_mask, const char *name) 360 { 361 m_event_names[event_mask] = name; 362 } 363 364 const char * GetEventName(uint32_t event_mask)365 GetEventName (uint32_t event_mask) const 366 { 367 event_names_map::const_iterator pos = m_event_names.find (event_mask); 368 if (pos != m_event_names.end()) 369 return pos->second.c_str(); 370 return NULL; 371 } 372 373 bool 374 EventTypeHasListeners (uint32_t event_type); 375 376 //------------------------------------------------------------------ 377 /// Removes a Listener from this broadcasters list and frees the 378 /// event bits specified by \a event_mask that were previously 379 /// acquired by \a listener (assuming \a listener was listening to 380 /// this object) for other listener objects to use. 381 /// 382 /// @param[in] listener 383 /// A Listener object that previously called AddListener. 384 /// 385 /// @param[in] event_mask 386 /// The event bits \a listener wishes to relinquish. 387 /// 388 /// @return 389 /// \b True if the listener was listening to this broadcaster 390 /// and was removed, \b false otherwise. 391 /// 392 /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t) 393 //------------------------------------------------------------------ 394 bool 395 RemoveListener (Listener* listener, uint32_t event_mask = UINT32_MAX); 396 397 //------------------------------------------------------------------ 398 /// Provides a simple mechanism to temporarily redirect events from 399 /// broadcaster. When you call this function passing in a listener and 400 /// event type mask, all events from the broadcaster matching the mask 401 /// will now go to the hijacking listener. 402 /// Only one hijack can occur at a time. If we need more than this we 403 /// will have to implement a Listener stack. 404 /// 405 /// @param[in] listener 406 /// A Listener object. You do not need to call StartListeningForEvents 407 /// for this broadcaster (that would fail anyway since the event bits 408 /// would most likely be taken by the listener(s) you are usurping. 409 /// 410 /// @param[in] event_mask 411 /// The event bits \a listener wishes to hijack. 412 /// 413 /// @return 414 /// \b True if the event mask could be hijacked, \b false otherwise. 415 /// 416 /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t) 417 //------------------------------------------------------------------ 418 bool 419 HijackBroadcaster (Listener *listener, uint32_t event_mask = UINT32_MAX); 420 421 bool IsHijackedForEvent(uint32_t event_mask)422 IsHijackedForEvent (uint32_t event_mask) 423 { 424 if (m_hijacking_listeners.size() > 0) 425 return (event_mask & m_hijacking_masks.back()) != 0; 426 return false; 427 } 428 429 //------------------------------------------------------------------ 430 /// Restore the state of the Broadcaster from a previous hijack attempt. 431 /// 432 //------------------------------------------------------------------ 433 void 434 RestoreBroadcaster (); 435 436 // This needs to be filled in if you are going to register the broadcaster with the broadcaster 437 // manager and do broadcaster class matching. 438 // FIXME: Probably should make a ManagedBroadcaster subclass with all the bits needed to work 439 // with the BroadcasterManager, so that it is clearer how to add one. 440 virtual ConstString &GetBroadcasterClass() const; 441 442 BroadcasterManager *GetManager(); 443 444 protected: 445 446 447 void 448 PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique); 449 450 //------------------------------------------------------------------ 451 // Classes that inherit from Broadcaster can see and modify these 452 //------------------------------------------------------------------ 453 typedef std::vector< std::pair<Listener*,uint32_t> > collection; 454 typedef std::map<uint32_t, std::string> event_names_map; 455 // Prefix the name of our member variables with "m_broadcaster_" 456 // since this is a class that gets subclassed. 457 const ConstString m_broadcaster_name; ///< The name of this broadcaster object. 458 event_names_map m_event_names; ///< Optionally define event names for readability and logging for each event bit 459 collection m_listeners; ///< A list of Listener / event_mask pairs that are listening to this broadcaster. 460 Mutex m_listeners_mutex; ///< A mutex that protects \a m_listeners. 461 std::vector<Listener *> m_hijacking_listeners; // A simple mechanism to intercept events from a broadcaster 462 std::vector<uint32_t> m_hijacking_masks; // At some point we may want to have a stack or Listener 463 // collections, but for now this is just for private hijacking. 464 BroadcasterManager *m_manager; 465 466 private: 467 //------------------------------------------------------------------ 468 // For Broadcaster only 469 //------------------------------------------------------------------ 470 DISALLOW_COPY_AND_ASSIGN (Broadcaster); 471 }; 472 473 } // namespace lldb_private 474 475 #endif // liblldb_Broadcaster_h_ 476