1 //===-- Event.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_EVENT_H 10 #define LLDB_UTILITY_EVENT_H 11 12 #include "lldb/Utility/Broadcaster.h" 13 #include "lldb/Utility/Predicate.h" 14 #include "lldb/Utility/StructuredData.h" 15 #include "lldb/lldb-defines.h" 16 #include "lldb/lldb-forward.h" 17 18 #include "llvm/ADT/StringRef.h" 19 20 #include <chrono> 21 #include <memory> 22 #include <string> 23 24 #include <cstddef> 25 #include <cstdint> 26 27 namespace lldb_private { 28 class Event; 29 class Stream; 30 } 31 32 namespace lldb_private { 33 34 // lldb::EventData 35 class EventData { 36 friend class Event; 37 38 public: 39 EventData(); 40 41 virtual ~EventData(); 42 43 virtual llvm::StringRef GetFlavor() const = 0; 44 GetLogChannel()45 virtual Log *GetLogChannel() { return nullptr; } 46 47 virtual void Dump(Stream *s) const; 48 49 private: 50 /// This will be queried for a Broadcaster with a primary and some secondary 51 /// listeners after the primary listener pulled the event from the event queue 52 /// and ran its DoOnRemoval, right before the event is delivered. 53 /// If it returns true, the event will also be forwarded to the secondary 54 /// listeners, and if false, event propagation stops at the primary listener. 55 /// Some broadcasters (particularly the Process broadcaster) fetch events on 56 /// a private Listener, and then forward the event to the Public Listeners 57 /// after some processing. The Process broadcaster does not want to forward 58 /// to the secondary listeners at the private processing stage. ForwardEventToPendingListeners(Event * event_ptr)59 virtual bool ForwardEventToPendingListeners(Event *event_ptr) { return true; } 60 DoOnRemoval(Event * event_ptr)61 virtual void DoOnRemoval(Event *event_ptr) {} 62 63 EventData(const EventData &) = delete; 64 const EventData &operator=(const EventData &) = delete; 65 }; 66 67 // lldb::EventDataBytes 68 class EventDataBytes : public EventData { 69 public: 70 // Constructors 71 EventDataBytes(); 72 73 EventDataBytes(llvm::StringRef str); 74 75 ~EventDataBytes() override; 76 77 // Member functions 78 llvm::StringRef GetFlavor() const override; 79 80 void Dump(Stream *s) const override; 81 82 const void *GetBytes() const; 83 84 size_t GetByteSize() const; 85 86 // Static functions 87 static const EventDataBytes *GetEventDataFromEvent(const Event *event_ptr); 88 89 static const void *GetBytesFromEvent(const Event *event_ptr); 90 91 static size_t GetByteSizeFromEvent(const Event *event_ptr); 92 93 static llvm::StringRef GetFlavorString(); 94 95 private: 96 std::string m_bytes; 97 98 EventDataBytes(const EventDataBytes &) = delete; 99 const EventDataBytes &operator=(const EventDataBytes &) = delete; 100 }; 101 102 class EventDataReceipt : public EventData { 103 public: EventDataReceipt()104 EventDataReceipt() : m_predicate(false) {} 105 106 ~EventDataReceipt() override = default; 107 108 static llvm::StringRef GetFlavorString(); 109 GetFlavor()110 llvm::StringRef GetFlavor() const override { return GetFlavorString(); } 111 112 bool WaitForEventReceived(const Timeout<std::micro> &timeout = std::nullopt) { 113 return m_predicate.WaitForValueEqualTo(true, timeout); 114 } 115 116 private: 117 Predicate<bool> m_predicate; 118 DoOnRemoval(Event * event_ptr)119 void DoOnRemoval(Event *event_ptr) override { 120 m_predicate.SetValue(true, eBroadcastAlways); 121 } 122 }; 123 124 /// This class handles one or more StructuredData::Dictionary entries 125 /// that are raised for structured data events. 126 127 class EventDataStructuredData : public EventData { 128 public: 129 // Constructors 130 EventDataStructuredData(); 131 132 EventDataStructuredData(const lldb::ProcessSP &process_sp, 133 const StructuredData::ObjectSP &object_sp, 134 const lldb::StructuredDataPluginSP &plugin_sp); 135 136 ~EventDataStructuredData() override; 137 138 // Member functions 139 llvm::StringRef GetFlavor() const override; 140 141 void Dump(Stream *s) const override; 142 143 const lldb::ProcessSP &GetProcess() const; 144 145 const StructuredData::ObjectSP &GetObject() const; 146 147 const lldb::StructuredDataPluginSP &GetStructuredDataPlugin() const; 148 149 void SetProcess(const lldb::ProcessSP &process_sp); 150 151 void SetObject(const StructuredData::ObjectSP &object_sp); 152 153 void SetStructuredDataPlugin(const lldb::StructuredDataPluginSP &plugin_sp); 154 155 // Static functions 156 static const EventDataStructuredData * 157 GetEventDataFromEvent(const Event *event_ptr); 158 159 static lldb::ProcessSP GetProcessFromEvent(const Event *event_ptr); 160 161 static StructuredData::ObjectSP GetObjectFromEvent(const Event *event_ptr); 162 163 static lldb::StructuredDataPluginSP 164 GetPluginFromEvent(const Event *event_ptr); 165 166 static llvm::StringRef GetFlavorString(); 167 168 private: 169 lldb::ProcessSP m_process_sp; 170 StructuredData::ObjectSP m_object_sp; 171 lldb::StructuredDataPluginSP m_plugin_sp; 172 173 EventDataStructuredData(const EventDataStructuredData &) = delete; 174 const EventDataStructuredData & 175 operator=(const EventDataStructuredData &) = delete; 176 }; 177 178 // lldb::Event 179 class Event : public std::enable_shared_from_this<Event> { 180 friend class Listener; 181 friend class EventData; 182 friend class Broadcaster::BroadcasterImpl; 183 184 public: 185 Event(Broadcaster *broadcaster, uint32_t event_type, 186 EventData *data = nullptr); 187 188 Event(Broadcaster *broadcaster, uint32_t event_type, 189 const lldb::EventDataSP &event_data_sp); 190 191 Event(uint32_t event_type, EventData *data = nullptr); 192 193 Event(uint32_t event_type, const lldb::EventDataSP &event_data_sp); 194 195 ~Event(); 196 197 void Dump(Stream *s) const; 198 GetData()199 EventData *GetData() { return m_data_sp.get(); } 200 GetData()201 const EventData *GetData() const { return m_data_sp.get(); } 202 SetData(EventData * new_data)203 void SetData(EventData *new_data) { m_data_sp.reset(new_data); } 204 GetType()205 uint32_t GetType() const { return m_type; } 206 SetType(uint32_t new_type)207 void SetType(uint32_t new_type) { m_type = new_type; } 208 GetBroadcaster()209 Broadcaster *GetBroadcaster() const { 210 Broadcaster::BroadcasterImplSP broadcaster_impl_sp = 211 m_broadcaster_wp.lock(); 212 if (broadcaster_impl_sp) 213 return broadcaster_impl_sp->GetBroadcaster(); 214 else 215 return nullptr; 216 } 217 BroadcasterIs(Broadcaster * broadcaster)218 bool BroadcasterIs(Broadcaster *broadcaster) { 219 Broadcaster::BroadcasterImplSP broadcaster_impl_sp = 220 m_broadcaster_wp.lock(); 221 if (broadcaster_impl_sp) 222 return broadcaster_impl_sp->GetBroadcaster() == broadcaster; 223 else 224 return false; 225 } 226 Clear()227 void Clear() { m_data_sp.reset(); } 228 229 /// This is used by Broadcasters with Primary Listeners to store the other 230 /// Listeners till after the Event's DoOnRemoval has completed. AddPendingListener(lldb::ListenerSP pending_listener_sp)231 void AddPendingListener(lldb::ListenerSP pending_listener_sp) { 232 m_pending_listeners.push_back(pending_listener_sp); 233 }; 234 235 private: 236 // This is only called by Listener when it pops an event off the queue for 237 // the listener. It calls the Event Data's DoOnRemoval() method, which is 238 // virtual and can be overridden by the specific data classes. 239 240 void DoOnRemoval(); 241 242 // Called by Broadcaster::BroadcastEvent prior to letting all the listeners 243 // know about it update the contained broadcaster so that events can be 244 // popped off one queue and re-broadcast to others. SetBroadcaster(Broadcaster * broadcaster)245 void SetBroadcaster(Broadcaster *broadcaster) { 246 m_broadcaster_wp = broadcaster->GetBroadcasterImpl(); 247 } 248 249 Broadcaster::BroadcasterImplWP 250 m_broadcaster_wp; // The broadcaster that sent this event 251 uint32_t m_type; // The bit describing this event 252 lldb::EventDataSP m_data_sp; // User specific data for this event 253 std::vector<lldb::ListenerSP> m_pending_listeners; 254 std::mutex m_listeners_mutex; 255 256 Event(const Event &) = delete; 257 const Event &operator=(const Event &) = delete; 258 Event() = delete; 259 }; 260 261 } // namespace lldb_private 262 263 #endif // LLDB_UTILITY_EVENT_H 264