1 //===-- SBListener.cpp ----------------------------------------------------===//
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 #include "lldb/API/SBListener.h"
10 #include "lldb/API/SBBroadcaster.h"
11 #include "lldb/API/SBDebugger.h"
12 #include "lldb/API/SBEvent.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/Core/Debugger.h"
15 #include "lldb/Utility/Broadcaster.h"
16 #include "lldb/Utility/Instrumentation.h"
17 #include "lldb/Utility/Listener.h"
18 #include "lldb/Utility/StreamString.h"
19
20 using namespace lldb;
21 using namespace lldb_private;
22
SBListener()23 SBListener::SBListener() { LLDB_INSTRUMENT_VA(this); }
24
SBListener(const char * name)25 SBListener::SBListener(const char *name)
26 : m_opaque_sp(Listener::MakeListener(name)) {
27 LLDB_INSTRUMENT_VA(this, name);
28 }
29
SBListener(const SBListener & rhs)30 SBListener::SBListener(const SBListener &rhs) : m_opaque_sp(rhs.m_opaque_sp) {
31 LLDB_INSTRUMENT_VA(this, rhs);
32 }
33
operator =(const lldb::SBListener & rhs)34 const lldb::SBListener &SBListener::operator=(const lldb::SBListener &rhs) {
35 LLDB_INSTRUMENT_VA(this, rhs);
36
37 if (this != &rhs) {
38 m_opaque_sp = rhs.m_opaque_sp;
39 m_unused_ptr = nullptr;
40 }
41 return *this;
42 }
43
SBListener(const lldb::ListenerSP & listener_sp)44 SBListener::SBListener(const lldb::ListenerSP &listener_sp)
45 : m_opaque_sp(listener_sp) {}
46
47 SBListener::~SBListener() = default;
48
IsValid() const49 bool SBListener::IsValid() const {
50 LLDB_INSTRUMENT_VA(this);
51 return this->operator bool();
52 }
operator bool() const53 SBListener::operator bool() const {
54 LLDB_INSTRUMENT_VA(this);
55
56 return m_opaque_sp != nullptr;
57 }
58
AddEvent(const SBEvent & event)59 void SBListener::AddEvent(const SBEvent &event) {
60 LLDB_INSTRUMENT_VA(this, event);
61
62 EventSP &event_sp = event.GetSP();
63 if (event_sp)
64 m_opaque_sp->AddEvent(event_sp);
65 }
66
Clear()67 void SBListener::Clear() {
68 LLDB_INSTRUMENT_VA(this);
69
70 if (m_opaque_sp)
71 m_opaque_sp->Clear();
72 }
73
StartListeningForEventClass(SBDebugger & debugger,const char * broadcaster_class,uint32_t event_mask)74 uint32_t SBListener::StartListeningForEventClass(SBDebugger &debugger,
75 const char *broadcaster_class,
76 uint32_t event_mask) {
77 LLDB_INSTRUMENT_VA(this, debugger, broadcaster_class, event_mask);
78
79 if (m_opaque_sp) {
80 Debugger *lldb_debugger = debugger.get();
81 if (!lldb_debugger)
82 return 0;
83 BroadcastEventSpec event_spec(ConstString(broadcaster_class), event_mask);
84 return m_opaque_sp->StartListeningForEventSpec(
85 lldb_debugger->GetBroadcasterManager(), event_spec);
86 } else
87 return 0;
88 }
89
StopListeningForEventClass(SBDebugger & debugger,const char * broadcaster_class,uint32_t event_mask)90 bool SBListener::StopListeningForEventClass(SBDebugger &debugger,
91 const char *broadcaster_class,
92 uint32_t event_mask) {
93 LLDB_INSTRUMENT_VA(this, debugger, broadcaster_class, event_mask);
94
95 if (m_opaque_sp) {
96 Debugger *lldb_debugger = debugger.get();
97 if (!lldb_debugger)
98 return false;
99 BroadcastEventSpec event_spec(ConstString(broadcaster_class), event_mask);
100 return m_opaque_sp->StopListeningForEventSpec(
101 lldb_debugger->GetBroadcasterManager(), event_spec);
102 } else
103 return false;
104 }
105
StartListeningForEvents(const SBBroadcaster & broadcaster,uint32_t event_mask)106 uint32_t SBListener::StartListeningForEvents(const SBBroadcaster &broadcaster,
107 uint32_t event_mask) {
108 LLDB_INSTRUMENT_VA(this, broadcaster, event_mask);
109
110 uint32_t acquired_event_mask = 0;
111 if (m_opaque_sp && broadcaster.IsValid()) {
112 acquired_event_mask =
113 m_opaque_sp->StartListeningForEvents(broadcaster.get(), event_mask);
114 }
115
116 return acquired_event_mask;
117 }
118
StopListeningForEvents(const SBBroadcaster & broadcaster,uint32_t event_mask)119 bool SBListener::StopListeningForEvents(const SBBroadcaster &broadcaster,
120 uint32_t event_mask) {
121 LLDB_INSTRUMENT_VA(this, broadcaster, event_mask);
122
123 if (m_opaque_sp && broadcaster.IsValid()) {
124 return m_opaque_sp->StopListeningForEvents(broadcaster.get(), event_mask);
125 }
126 return false;
127 }
128
WaitForEvent(uint32_t timeout_secs,SBEvent & event)129 bool SBListener::WaitForEvent(uint32_t timeout_secs, SBEvent &event) {
130 LLDB_INSTRUMENT_VA(this, timeout_secs, event);
131
132 bool success = false;
133
134 if (m_opaque_sp) {
135 Timeout<std::micro> timeout(std::nullopt);
136 if (timeout_secs != UINT32_MAX) {
137 assert(timeout_secs != 0); // Take this out after all calls with timeout
138 // set to zero have been removed....
139 timeout = std::chrono::seconds(timeout_secs);
140 }
141 EventSP event_sp;
142 if (m_opaque_sp->GetEvent(event_sp, timeout)) {
143 event.reset(event_sp);
144 success = true;
145 }
146 }
147
148 if (!success)
149 event.reset(nullptr);
150 return success;
151 }
152
WaitForEventForBroadcaster(uint32_t num_seconds,const SBBroadcaster & broadcaster,SBEvent & event)153 bool SBListener::WaitForEventForBroadcaster(uint32_t num_seconds,
154 const SBBroadcaster &broadcaster,
155 SBEvent &event) {
156 LLDB_INSTRUMENT_VA(this, num_seconds, broadcaster, event);
157
158 if (m_opaque_sp && broadcaster.IsValid()) {
159 Timeout<std::micro> timeout(std::nullopt);
160 if (num_seconds != UINT32_MAX)
161 timeout = std::chrono::seconds(num_seconds);
162 EventSP event_sp;
163 if (m_opaque_sp->GetEventForBroadcaster(broadcaster.get(), event_sp,
164 timeout)) {
165 event.reset(event_sp);
166 return true;
167 }
168 }
169 event.reset(nullptr);
170 return false;
171 }
172
WaitForEventForBroadcasterWithType(uint32_t num_seconds,const SBBroadcaster & broadcaster,uint32_t event_type_mask,SBEvent & event)173 bool SBListener::WaitForEventForBroadcasterWithType(
174 uint32_t num_seconds, const SBBroadcaster &broadcaster,
175 uint32_t event_type_mask, SBEvent &event) {
176 LLDB_INSTRUMENT_VA(this, num_seconds, broadcaster, event_type_mask, event);
177
178 if (m_opaque_sp && broadcaster.IsValid()) {
179 Timeout<std::micro> timeout(std::nullopt);
180 if (num_seconds != UINT32_MAX)
181 timeout = std::chrono::seconds(num_seconds);
182 EventSP event_sp;
183 if (m_opaque_sp->GetEventForBroadcasterWithType(
184 broadcaster.get(), event_type_mask, event_sp, timeout)) {
185 event.reset(event_sp);
186 return true;
187 }
188 }
189 event.reset(nullptr);
190 return false;
191 }
192
PeekAtNextEvent(SBEvent & event)193 bool SBListener::PeekAtNextEvent(SBEvent &event) {
194 LLDB_INSTRUMENT_VA(this, event);
195
196 if (m_opaque_sp) {
197 event.reset(m_opaque_sp->PeekAtNextEvent());
198 return event.IsValid();
199 }
200 event.reset(nullptr);
201 return false;
202 }
203
PeekAtNextEventForBroadcaster(const SBBroadcaster & broadcaster,SBEvent & event)204 bool SBListener::PeekAtNextEventForBroadcaster(const SBBroadcaster &broadcaster,
205 SBEvent &event) {
206 LLDB_INSTRUMENT_VA(this, broadcaster, event);
207
208 if (m_opaque_sp && broadcaster.IsValid()) {
209 event.reset(m_opaque_sp->PeekAtNextEventForBroadcaster(broadcaster.get()));
210 return event.IsValid();
211 }
212 event.reset(nullptr);
213 return false;
214 }
215
PeekAtNextEventForBroadcasterWithType(const SBBroadcaster & broadcaster,uint32_t event_type_mask,SBEvent & event)216 bool SBListener::PeekAtNextEventForBroadcasterWithType(
217 const SBBroadcaster &broadcaster, uint32_t event_type_mask,
218 SBEvent &event) {
219 LLDB_INSTRUMENT_VA(this, broadcaster, event_type_mask, event);
220
221 if (m_opaque_sp && broadcaster.IsValid()) {
222 event.reset(m_opaque_sp->PeekAtNextEventForBroadcasterWithType(
223 broadcaster.get(), event_type_mask));
224 return event.IsValid();
225 }
226 event.reset(nullptr);
227 return false;
228 }
229
GetNextEvent(SBEvent & event)230 bool SBListener::GetNextEvent(SBEvent &event) {
231 LLDB_INSTRUMENT_VA(this, event);
232
233 if (m_opaque_sp) {
234 EventSP event_sp;
235 if (m_opaque_sp->GetEvent(event_sp, std::chrono::seconds(0))) {
236 event.reset(event_sp);
237 return true;
238 }
239 }
240 event.reset(nullptr);
241 return false;
242 }
243
GetNextEventForBroadcaster(const SBBroadcaster & broadcaster,SBEvent & event)244 bool SBListener::GetNextEventForBroadcaster(const SBBroadcaster &broadcaster,
245 SBEvent &event) {
246 LLDB_INSTRUMENT_VA(this, broadcaster, event);
247
248 if (m_opaque_sp && broadcaster.IsValid()) {
249 EventSP event_sp;
250 if (m_opaque_sp->GetEventForBroadcaster(broadcaster.get(), event_sp,
251 std::chrono::seconds(0))) {
252 event.reset(event_sp);
253 return true;
254 }
255 }
256 event.reset(nullptr);
257 return false;
258 }
259
GetNextEventForBroadcasterWithType(const SBBroadcaster & broadcaster,uint32_t event_type_mask,SBEvent & event)260 bool SBListener::GetNextEventForBroadcasterWithType(
261 const SBBroadcaster &broadcaster, uint32_t event_type_mask,
262 SBEvent &event) {
263 LLDB_INSTRUMENT_VA(this, broadcaster, event_type_mask, event);
264
265 if (m_opaque_sp && broadcaster.IsValid()) {
266 EventSP event_sp;
267 if (m_opaque_sp->GetEventForBroadcasterWithType(broadcaster.get(),
268 event_type_mask, event_sp,
269 std::chrono::seconds(0))) {
270 event.reset(event_sp);
271 return true;
272 }
273 }
274 event.reset(nullptr);
275 return false;
276 }
277
HandleBroadcastEvent(const SBEvent & event)278 bool SBListener::HandleBroadcastEvent(const SBEvent &event) {
279 LLDB_INSTRUMENT_VA(this, event);
280
281 if (m_opaque_sp)
282 return m_opaque_sp->HandleBroadcastEvent(event.GetSP());
283 return false;
284 }
285
GetSP()286 lldb::ListenerSP SBListener::GetSP() { return m_opaque_sp; }
287
operator ->() const288 Listener *SBListener::operator->() const { return m_opaque_sp.get(); }
289
get() const290 Listener *SBListener::get() const { return m_opaque_sp.get(); }
291
reset(ListenerSP listener_sp)292 void SBListener::reset(ListenerSP listener_sp) {
293 m_opaque_sp = listener_sp;
294 m_unused_ptr = nullptr;
295 }
296