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

source code of lldb/include/lldb/Utility/Event.h