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