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