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