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
28namespace lldb_private {
29class Event;
30class Stream;
31}
32
33namespace lldb_private {
34
35// lldb::EventData
36class EventData {
37 friend class Event;
38
39public:
40 EventData();
41
42 virtual ~EventData();
43
44 virtual ConstString GetFlavor() const = 0;
45
46 virtual void Dump(Stream *s) const;
47
48private:
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
56class EventDataBytes : public EventData {
57public:
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
93private:
94 std::string m_bytes;
95
96 EventDataBytes(const EventDataBytes &) = delete;
97 const EventDataBytes &operator=(const EventDataBytes &) = delete;
98};
99
100class EventDataReceipt : public EventData {
101public:
102 EventDataReceipt() : EventData(), m_predicate(false) {}
103
104 ~EventDataReceipt() override {}
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
117private:
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
128class EventDataStructuredData : public EventData {
129public:
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
169private:
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
180class Event {
181 friend class Listener;
182 friend class EventData;
183 friend class Broadcaster::BroadcasterImpl;
184
185public:
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
230private:
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