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 
46   virtual void Dump(Stream *s) const;
47 
48 private:
49   virtual void DoOnRemoval(Event *event_ptr) {}
50 
51   EventData(const EventData &) = delete;
52   const EventData &operator=(const EventData &) = delete;
53 };
54 
55 // lldb::EventDataBytes
56 class EventDataBytes : public EventData {
57 public:
58   // Constructors
59   EventDataBytes();
60 
61   EventDataBytes(const char *cstr);
62 
63   EventDataBytes(llvm::StringRef str);
64 
65   EventDataBytes(const void *src, size_t src_len);
66 
67   ~EventDataBytes() override;
68 
69   // Member functions
70   ConstString GetFlavor() const override;
71 
72   void Dump(Stream *s) const override;
73 
74   const void *GetBytes() const;
75 
76   size_t GetByteSize() const;
77 
78   void SetBytes(const void *src, size_t src_len);
79 
80   void SwapBytes(std::string &new_bytes);
81 
82   void SetBytesFromCString(const char *cstr);
83 
84   // Static functions
85   static const EventDataBytes *GetEventDataFromEvent(const Event *event_ptr);
86 
87   static const void *GetBytesFromEvent(const Event *event_ptr);
88 
89   static size_t GetByteSizeFromEvent(const Event *event_ptr);
90 
91   static ConstString GetFlavorString();
92 
93 private:
94   std::string m_bytes;
95 
96   EventDataBytes(const EventDataBytes &) = delete;
97   const EventDataBytes &operator=(const EventDataBytes &) = delete;
98 };
99 
100 class EventDataReceipt : public EventData {
101 public:
102   EventDataReceipt() : m_predicate(false) {}
103 
104   ~EventDataReceipt() override = default;
105 
106   static ConstString GetFlavorString() {
107     static ConstString g_flavor("Process::ProcessEventData");
108     return g_flavor;
109   }
110 
111   ConstString GetFlavor() const override { return GetFlavorString(); }
112 
113   bool WaitForEventReceived(const Timeout<std::micro> &timeout = llvm::None) {
114     return m_predicate.WaitForValueEqualTo(true, timeout);
115   }
116 
117 private:
118   Predicate<bool> m_predicate;
119 
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   ConstString 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 ConstString 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 {
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 
200   EventData *GetData() { return m_data_sp.get(); }
201 
202   const EventData *GetData() const { return m_data_sp.get(); }
203 
204   void SetData(EventData *new_data) { m_data_sp.reset(new_data); }
205 
206   uint32_t GetType() const { return m_type; }
207 
208   void SetType(uint32_t new_type) { m_type = new_type; }
209 
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 
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 
228   void Clear() { m_data_sp.reset(); }
229 
230 private:
231   // This is only called by Listener when it pops an event off the queue for
232   // the listener.  It calls the Event Data's DoOnRemoval() method, which is
233   // virtual and can be overridden by the specific data classes.
234 
235   void DoOnRemoval();
236 
237   // Called by Broadcaster::BroadcastEvent prior to letting all the listeners
238   // know about it update the contained broadcaster so that events can be
239   // popped off one queue and re-broadcast to others.
240   void SetBroadcaster(Broadcaster *broadcaster) {
241     m_broadcaster_wp = broadcaster->GetBroadcasterImpl();
242   }
243 
244   Broadcaster::BroadcasterImplWP
245       m_broadcaster_wp;        // The broadcaster that sent this event
246   uint32_t m_type;             // The bit describing this event
247   lldb::EventDataSP m_data_sp; // User specific data for this event
248 
249   Event(const Event &) = delete;
250   const Event &operator=(const Event &) = delete;
251   Event() = delete;
252 };
253 
254 } // namespace lldb_private
255 
256 #endif // LLDB_UTILITY_EVENT_H
257