1254721Semaste//===-- SBListener.cpp ------------------------------------------*- C++ -*-===//
2254721Semaste//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6254721Semaste//
7254721Semaste//===----------------------------------------------------------------------===//
8254721Semaste
9254721Semaste#include "lldb/API/SBListener.h"
10353358Sdim#include "SBReproducerPrivate.h"
11254721Semaste#include "lldb/API/SBBroadcaster.h"
12254721Semaste#include "lldb/API/SBDebugger.h"
13254721Semaste#include "lldb/API/SBEvent.h"
14254721Semaste#include "lldb/API/SBStream.h"
15254721Semaste#include "lldb/Core/Debugger.h"
16344779Sdim#include "lldb/Utility/Broadcaster.h"
17344779Sdim#include "lldb/Utility/Listener.h"
18321369Sdim#include "lldb/Utility/StreamString.h"
19254721Semaste
20254721Semasteusing namespace lldb;
21254721Semasteusing namespace lldb_private;
22254721Semaste
23353358SdimSBListener::SBListener() : m_opaque_sp(), m_unused_ptr(nullptr) {
24353358Sdim  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBListener);
25353358Sdim}
26254721Semaste
27314564SdimSBListener::SBListener(const char *name)
28314564Sdim    : m_opaque_sp(Listener::MakeListener(name)), m_unused_ptr(nullptr) {
29353358Sdim  LLDB_RECORD_CONSTRUCTOR(SBListener, (const char *), name);
30254721Semaste}
31254721Semaste
32314564SdimSBListener::SBListener(const SBListener &rhs)
33353358Sdim    : m_opaque_sp(rhs.m_opaque_sp), m_unused_ptr(nullptr) {
34353358Sdim  LLDB_RECORD_CONSTRUCTOR(SBListener, (const lldb::SBListener &), rhs);
35353358Sdim}
36254721Semaste
37314564Sdimconst lldb::SBListener &SBListener::operator=(const lldb::SBListener &rhs) {
38353358Sdim  LLDB_RECORD_METHOD(const lldb::SBListener &,
39353358Sdim                     SBListener, operator=,(const lldb::SBListener &), rhs);
40353358Sdim
41314564Sdim  if (this != &rhs) {
42314564Sdim    m_opaque_sp = rhs.m_opaque_sp;
43314564Sdim    m_unused_ptr = nullptr;
44314564Sdim  }
45353358Sdim  return LLDB_RECORD_RESULT(*this);
46254721Semaste}
47254721Semaste
48314564SdimSBListener::SBListener(const lldb::ListenerSP &listener_sp)
49314564Sdim    : m_opaque_sp(listener_sp), m_unused_ptr(nullptr) {}
50254721Semaste
51314564SdimSBListener::~SBListener() {}
52280031Sdim
53353358Sdimbool SBListener::IsValid() const {
54353358Sdim  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBListener, IsValid);
55353358Sdim  return this->operator bool();
56353358Sdim}
57353358SdimSBListener::operator bool() const {
58353358Sdim  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBListener, operator bool);
59254721Semaste
60353358Sdim  return m_opaque_sp != nullptr;
61353358Sdim}
62353358Sdim
63314564Sdimvoid SBListener::AddEvent(const SBEvent &event) {
64353358Sdim  LLDB_RECORD_METHOD(void, SBListener, AddEvent, (const lldb::SBEvent &),
65353358Sdim                     event);
66353358Sdim
67314564Sdim  EventSP &event_sp = event.GetSP();
68314564Sdim  if (event_sp)
69314564Sdim    m_opaque_sp->AddEvent(event_sp);
70254721Semaste}
71254721Semaste
72314564Sdimvoid SBListener::Clear() {
73353358Sdim  LLDB_RECORD_METHOD_NO_ARGS(void, SBListener, Clear);
74353358Sdim
75314564Sdim  if (m_opaque_sp)
76314564Sdim    m_opaque_sp->Clear();
77254721Semaste}
78254721Semaste
79314564Sdimuint32_t SBListener::StartListeningForEventClass(SBDebugger &debugger,
80314564Sdim                                                 const char *broadcaster_class,
81314564Sdim                                                 uint32_t event_mask) {
82353358Sdim  LLDB_RECORD_METHOD(uint32_t, SBListener, StartListeningForEventClass,
83353358Sdim                     (lldb::SBDebugger &, const char *, uint32_t), debugger,
84353358Sdim                     broadcaster_class, event_mask);
85353358Sdim
86314564Sdim  if (m_opaque_sp) {
87314564Sdim    Debugger *lldb_debugger = debugger.get();
88314564Sdim    if (!lldb_debugger)
89314564Sdim      return 0;
90314564Sdim    BroadcastEventSpec event_spec(ConstString(broadcaster_class), event_mask);
91314564Sdim    return m_opaque_sp->StartListeningForEventSpec(
92314564Sdim        lldb_debugger->GetBroadcasterManager(), event_spec);
93314564Sdim  } else
94314564Sdim    return 0;
95254721Semaste}
96254721Semaste
97314564Sdimbool SBListener::StopListeningForEventClass(SBDebugger &debugger,
98314564Sdim                                            const char *broadcaster_class,
99314564Sdim                                            uint32_t event_mask) {
100353358Sdim  LLDB_RECORD_METHOD(bool, SBListener, StopListeningForEventClass,
101353358Sdim                     (lldb::SBDebugger &, const char *, uint32_t), debugger,
102353358Sdim                     broadcaster_class, event_mask);
103353358Sdim
104314564Sdim  if (m_opaque_sp) {
105314564Sdim    Debugger *lldb_debugger = debugger.get();
106314564Sdim    if (!lldb_debugger)
107314564Sdim      return false;
108314564Sdim    BroadcastEventSpec event_spec(ConstString(broadcaster_class), event_mask);
109314564Sdim    return m_opaque_sp->StopListeningForEventSpec(
110314564Sdim        lldb_debugger->GetBroadcasterManager(), event_spec);
111314564Sdim  } else
112314564Sdim    return false;
113254721Semaste}
114276479Sdim
115314564Sdimuint32_t SBListener::StartListeningForEvents(const SBBroadcaster &broadcaster,
116314564Sdim                                             uint32_t event_mask) {
117353358Sdim  LLDB_RECORD_METHOD(uint32_t, SBListener, StartListeningForEvents,
118353358Sdim                     (const lldb::SBBroadcaster &, uint32_t), broadcaster,
119353358Sdim                     event_mask);
120353358Sdim
121314564Sdim  uint32_t acquired_event_mask = 0;
122314564Sdim  if (m_opaque_sp && broadcaster.IsValid()) {
123314564Sdim    acquired_event_mask =
124314564Sdim        m_opaque_sp->StartListeningForEvents(broadcaster.get(), event_mask);
125314564Sdim  }
126276479Sdim
127314564Sdim  return acquired_event_mask;
128254721Semaste}
129254721Semaste
130314564Sdimbool SBListener::StopListeningForEvents(const SBBroadcaster &broadcaster,
131314564Sdim                                        uint32_t event_mask) {
132353358Sdim  LLDB_RECORD_METHOD(bool, SBListener, StopListeningForEvents,
133353358Sdim                     (const lldb::SBBroadcaster &, uint32_t), broadcaster,
134353358Sdim                     event_mask);
135353358Sdim
136314564Sdim  if (m_opaque_sp && broadcaster.IsValid()) {
137314564Sdim    return m_opaque_sp->StopListeningForEvents(broadcaster.get(), event_mask);
138314564Sdim  }
139314564Sdim  return false;
140254721Semaste}
141254721Semaste
142314564Sdimbool SBListener::WaitForEvent(uint32_t timeout_secs, SBEvent &event) {
143353358Sdim  LLDB_RECORD_METHOD(bool, SBListener, WaitForEvent,
144353358Sdim                     (uint32_t, lldb::SBEvent &), timeout_secs, event);
145353358Sdim
146314564Sdim  bool success = false;
147254721Semaste
148314564Sdim  if (m_opaque_sp) {
149314564Sdim    Timeout<std::micro> timeout(llvm::None);
150314564Sdim    if (timeout_secs != UINT32_MAX) {
151314564Sdim      assert(timeout_secs != 0); // Take this out after all calls with timeout
152314564Sdim                                 // set to zero have been removed....
153314564Sdim      timeout = std::chrono::seconds(timeout_secs);
154254721Semaste    }
155314564Sdim    EventSP event_sp;
156314564Sdim    if (m_opaque_sp->GetEvent(event_sp, timeout)) {
157314564Sdim      event.reset(event_sp);
158314564Sdim      success = true;
159314564Sdim    }
160314564Sdim  }
161254721Semaste
162314564Sdim  if (!success)
163353358Sdim    event.reset(nullptr);
164314564Sdim  return success;
165254721Semaste}
166254721Semaste
167314564Sdimbool SBListener::WaitForEventForBroadcaster(uint32_t num_seconds,
168314564Sdim                                            const SBBroadcaster &broadcaster,
169314564Sdim                                            SBEvent &event) {
170353358Sdim  LLDB_RECORD_METHOD(bool, SBListener, WaitForEventForBroadcaster,
171353358Sdim                     (uint32_t, const lldb::SBBroadcaster &, lldb::SBEvent &),
172353358Sdim                     num_seconds, broadcaster, event);
173353358Sdim
174314564Sdim  if (m_opaque_sp && broadcaster.IsValid()) {
175314564Sdim    Timeout<std::micro> timeout(llvm::None);
176314564Sdim    if (num_seconds != UINT32_MAX)
177314564Sdim      timeout = std::chrono::seconds(num_seconds);
178314564Sdim    EventSP event_sp;
179314564Sdim    if (m_opaque_sp->GetEventForBroadcaster(broadcaster.get(), event_sp,
180314564Sdim                                            timeout)) {
181314564Sdim      event.reset(event_sp);
182314564Sdim      return true;
183254721Semaste    }
184314564Sdim  }
185353358Sdim  event.reset(nullptr);
186314564Sdim  return false;
187254721Semaste}
188254721Semaste
189314564Sdimbool SBListener::WaitForEventForBroadcasterWithType(
190314564Sdim    uint32_t num_seconds, const SBBroadcaster &broadcaster,
191314564Sdim    uint32_t event_type_mask, SBEvent &event) {
192353358Sdim  LLDB_RECORD_METHOD(
193353358Sdim      bool, SBListener, WaitForEventForBroadcasterWithType,
194353358Sdim      (uint32_t, const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &),
195353358Sdim      num_seconds, broadcaster, event_type_mask, event);
196353358Sdim
197314564Sdim  if (m_opaque_sp && broadcaster.IsValid()) {
198314564Sdim    Timeout<std::micro> timeout(llvm::None);
199314564Sdim    if (num_seconds != UINT32_MAX)
200314564Sdim      timeout = std::chrono::seconds(num_seconds);
201314564Sdim    EventSP event_sp;
202314564Sdim    if (m_opaque_sp->GetEventForBroadcasterWithType(
203314564Sdim            broadcaster.get(), event_type_mask, event_sp, timeout)) {
204314564Sdim      event.reset(event_sp);
205314564Sdim      return true;
206254721Semaste    }
207314564Sdim  }
208353358Sdim  event.reset(nullptr);
209314564Sdim  return false;
210254721Semaste}
211254721Semaste
212314564Sdimbool SBListener::PeekAtNextEvent(SBEvent &event) {
213353358Sdim  LLDB_RECORD_METHOD(bool, SBListener, PeekAtNextEvent, (lldb::SBEvent &),
214353358Sdim                     event);
215353358Sdim
216314564Sdim  if (m_opaque_sp) {
217314564Sdim    event.reset(m_opaque_sp->PeekAtNextEvent());
218314564Sdim    return event.IsValid();
219314564Sdim  }
220353358Sdim  event.reset(nullptr);
221314564Sdim  return false;
222254721Semaste}
223254721Semaste
224314564Sdimbool SBListener::PeekAtNextEventForBroadcaster(const SBBroadcaster &broadcaster,
225314564Sdim                                               SBEvent &event) {
226353358Sdim  LLDB_RECORD_METHOD(bool, SBListener, PeekAtNextEventForBroadcaster,
227353358Sdim                     (const lldb::SBBroadcaster &, lldb::SBEvent &),
228353358Sdim                     broadcaster, event);
229353358Sdim
230314564Sdim  if (m_opaque_sp && broadcaster.IsValid()) {
231314564Sdim    event.reset(m_opaque_sp->PeekAtNextEventForBroadcaster(broadcaster.get()));
232314564Sdim    return event.IsValid();
233314564Sdim  }
234353358Sdim  event.reset(nullptr);
235314564Sdim  return false;
236254721Semaste}
237254721Semaste
238314564Sdimbool SBListener::PeekAtNextEventForBroadcasterWithType(
239314564Sdim    const SBBroadcaster &broadcaster, uint32_t event_type_mask,
240314564Sdim    SBEvent &event) {
241353358Sdim  LLDB_RECORD_METHOD(bool, SBListener, PeekAtNextEventForBroadcasterWithType,
242353358Sdim                     (const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &),
243353358Sdim                     broadcaster, event_type_mask, event);
244353358Sdim
245314564Sdim  if (m_opaque_sp && broadcaster.IsValid()) {
246314564Sdim    event.reset(m_opaque_sp->PeekAtNextEventForBroadcasterWithType(
247314564Sdim        broadcaster.get(), event_type_mask));
248314564Sdim    return event.IsValid();
249314564Sdim  }
250353358Sdim  event.reset(nullptr);
251314564Sdim  return false;
252254721Semaste}
253254721Semaste
254314564Sdimbool SBListener::GetNextEvent(SBEvent &event) {
255353358Sdim  LLDB_RECORD_METHOD(bool, SBListener, GetNextEvent, (lldb::SBEvent &), event);
256353358Sdim
257314564Sdim  if (m_opaque_sp) {
258314564Sdim    EventSP event_sp;
259314564Sdim    if (m_opaque_sp->GetEvent(event_sp, std::chrono::seconds(0))) {
260314564Sdim      event.reset(event_sp);
261314564Sdim      return true;
262254721Semaste    }
263314564Sdim  }
264353358Sdim  event.reset(nullptr);
265314564Sdim  return false;
266254721Semaste}
267254721Semaste
268314564Sdimbool SBListener::GetNextEventForBroadcaster(const SBBroadcaster &broadcaster,
269314564Sdim                                            SBEvent &event) {
270353358Sdim  LLDB_RECORD_METHOD(bool, SBListener, GetNextEventForBroadcaster,
271353358Sdim                     (const lldb::SBBroadcaster &, lldb::SBEvent &),
272353358Sdim                     broadcaster, event);
273353358Sdim
274314564Sdim  if (m_opaque_sp && broadcaster.IsValid()) {
275314564Sdim    EventSP event_sp;
276314564Sdim    if (m_opaque_sp->GetEventForBroadcaster(broadcaster.get(), event_sp,
277314564Sdim                                            std::chrono::seconds(0))) {
278314564Sdim      event.reset(event_sp);
279314564Sdim      return true;
280254721Semaste    }
281314564Sdim  }
282353358Sdim  event.reset(nullptr);
283314564Sdim  return false;
284254721Semaste}
285254721Semaste
286314564Sdimbool SBListener::GetNextEventForBroadcasterWithType(
287314564Sdim    const SBBroadcaster &broadcaster, uint32_t event_type_mask,
288314564Sdim    SBEvent &event) {
289353358Sdim  LLDB_RECORD_METHOD(bool, SBListener, GetNextEventForBroadcasterWithType,
290353358Sdim                     (const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &),
291353358Sdim                     broadcaster, event_type_mask, event);
292353358Sdim
293314564Sdim  if (m_opaque_sp && broadcaster.IsValid()) {
294314564Sdim    EventSP event_sp;
295314564Sdim    if (m_opaque_sp->GetEventForBroadcasterWithType(broadcaster.get(),
296314564Sdim                                                    event_type_mask, event_sp,
297314564Sdim                                                    std::chrono::seconds(0))) {
298314564Sdim      event.reset(event_sp);
299314564Sdim      return true;
300254721Semaste    }
301314564Sdim  }
302353358Sdim  event.reset(nullptr);
303314564Sdim  return false;
304254721Semaste}
305254721Semaste
306314564Sdimbool SBListener::HandleBroadcastEvent(const SBEvent &event) {
307353358Sdim  LLDB_RECORD_METHOD(bool, SBListener, HandleBroadcastEvent,
308353358Sdim                     (const lldb::SBEvent &), event);
309353358Sdim
310314564Sdim  if (m_opaque_sp)
311314564Sdim    return m_opaque_sp->HandleBroadcastEvent(event.GetSP());
312314564Sdim  return false;
313254721Semaste}
314254721Semaste
315321369Sdimlldb::ListenerSP SBListener::GetSP() { return m_opaque_sp; }
316321369Sdim
317314564SdimListener *SBListener::operator->() const { return m_opaque_sp.get(); }
318254721Semaste
319314564SdimListener *SBListener::get() const { return m_opaque_sp.get(); }
320254721Semaste
321314564Sdimvoid SBListener::reset(ListenerSP listener_sp) {
322314564Sdim  m_opaque_sp = listener_sp;
323314564Sdim  m_unused_ptr = nullptr;
324254721Semaste}
325353358Sdim
326353358Sdimnamespace lldb_private {
327353358Sdimnamespace repro {
328353358Sdim
329353358Sdimtemplate <>
330353358Sdimvoid RegisterMethods<SBListener>(Registry &R) {
331353358Sdim  LLDB_REGISTER_CONSTRUCTOR(SBListener, ());
332353358Sdim  LLDB_REGISTER_CONSTRUCTOR(SBListener, (const char *));
333353358Sdim  LLDB_REGISTER_CONSTRUCTOR(SBListener, (const lldb::SBListener &));
334353358Sdim  LLDB_REGISTER_METHOD(const lldb::SBListener &,
335353358Sdim                       SBListener, operator=,(const lldb::SBListener &));
336353358Sdim  LLDB_REGISTER_METHOD_CONST(bool, SBListener, IsValid, ());
337353358Sdim  LLDB_REGISTER_METHOD_CONST(bool, SBListener, operator bool, ());
338353358Sdim  LLDB_REGISTER_METHOD(void, SBListener, AddEvent, (const lldb::SBEvent &));
339353358Sdim  LLDB_REGISTER_METHOD(void, SBListener, Clear, ());
340353358Sdim  LLDB_REGISTER_METHOD(uint32_t, SBListener, StartListeningForEventClass,
341353358Sdim                       (lldb::SBDebugger &, const char *, uint32_t));
342353358Sdim  LLDB_REGISTER_METHOD(bool, SBListener, StopListeningForEventClass,
343353358Sdim                       (lldb::SBDebugger &, const char *, uint32_t));
344353358Sdim  LLDB_REGISTER_METHOD(uint32_t, SBListener, StartListeningForEvents,
345353358Sdim                       (const lldb::SBBroadcaster &, uint32_t));
346353358Sdim  LLDB_REGISTER_METHOD(bool, SBListener, StopListeningForEvents,
347353358Sdim                       (const lldb::SBBroadcaster &, uint32_t));
348353358Sdim  LLDB_REGISTER_METHOD(bool, SBListener, WaitForEvent,
349353358Sdim                       (uint32_t, lldb::SBEvent &));
350353358Sdim  LLDB_REGISTER_METHOD(
351353358Sdim      bool, SBListener, WaitForEventForBroadcaster,
352353358Sdim      (uint32_t, const lldb::SBBroadcaster &, lldb::SBEvent &));
353353358Sdim  LLDB_REGISTER_METHOD(
354353358Sdim      bool, SBListener, WaitForEventForBroadcasterWithType,
355353358Sdim      (uint32_t, const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &));
356353358Sdim  LLDB_REGISTER_METHOD(bool, SBListener, PeekAtNextEvent, (lldb::SBEvent &));
357353358Sdim  LLDB_REGISTER_METHOD(bool, SBListener, PeekAtNextEventForBroadcaster,
358353358Sdim                       (const lldb::SBBroadcaster &, lldb::SBEvent &));
359353358Sdim  LLDB_REGISTER_METHOD(
360353358Sdim      bool, SBListener, PeekAtNextEventForBroadcasterWithType,
361353358Sdim      (const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &));
362353358Sdim  LLDB_REGISTER_METHOD(bool, SBListener, GetNextEvent, (lldb::SBEvent &));
363353358Sdim  LLDB_REGISTER_METHOD(bool, SBListener, GetNextEventForBroadcaster,
364353358Sdim                       (const lldb::SBBroadcaster &, lldb::SBEvent &));
365353358Sdim  LLDB_REGISTER_METHOD(
366353358Sdim      bool, SBListener, GetNextEventForBroadcasterWithType,
367353358Sdim      (const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &));
368353358Sdim  LLDB_REGISTER_METHOD(bool, SBListener, HandleBroadcastEvent,
369353358Sdim                       (const lldb::SBEvent &));
370353358Sdim}
371353358Sdim
372353358Sdim}
373353358Sdim}
374