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