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