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(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   llvm::StringRef 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 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