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 23 SBListener::SBListener() { LLDB_INSTRUMENT_VA(this); } 24 25 SBListener::SBListener(const char *name) 26 : m_opaque_sp(Listener::MakeListener(name)) { 27 LLDB_INSTRUMENT_VA(this, name); 28 } 29 30 SBListener::SBListener(const SBListener &rhs) : m_opaque_sp(rhs.m_opaque_sp) { 31 LLDB_INSTRUMENT_VA(this, rhs); 32 } 33 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 44 SBListener::SBListener(const lldb::ListenerSP &listener_sp) 45 : m_opaque_sp(listener_sp) {} 46 47 SBListener::~SBListener() = default; 48 49 bool SBListener::IsValid() const { 50 LLDB_INSTRUMENT_VA(this); 51 return this->operator bool(); 52 } 53 SBListener::operator bool() const { 54 LLDB_INSTRUMENT_VA(this); 55 56 return m_opaque_sp != nullptr; 57 } 58 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 67 void SBListener::Clear() { 68 LLDB_INSTRUMENT_VA(this); 69 70 if (m_opaque_sp) 71 m_opaque_sp->Clear(); 72 } 73 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 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 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 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 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(llvm::None); 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 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(llvm::None); 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 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(llvm::None); 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 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 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 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 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 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 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 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 286 lldb::ListenerSP SBListener::GetSP() { return m_opaque_sp; } 287 288 Listener *SBListener::operator->() const { return m_opaque_sp.get(); } 289 290 Listener *SBListener::get() const { return m_opaque_sp.get(); } 291 292 void SBListener::reset(ListenerSP listener_sp) { 293 m_opaque_sp = listener_sp; 294 m_unused_ptr = nullptr; 295 } 296