28 m_manager_sp(std::move(manager_sp)), m_broadcaster_name(std::move(name)) {
30 LLDB_LOG(log,
"{0} Broadcaster::Broadcaster(\"{1}\")",
35 : m_broadcaster(broadcaster), m_listeners(), m_listeners_mutex(),
36 m_hijacking_listeners(), m_hijacking_masks() {}
40 LLDB_LOG(log,
"{0} Broadcaster::~Broadcaster(\"{1}\")",
52llvm::SmallVector<std::pair<ListenerSP, uint32_t &>, 4>
54 bool include_primary) {
55 llvm::SmallVector<std::pair<ListenerSP, uint32_t &>, 4> listeners;
56 size_t max_count = m_listeners.size();
59 listeners.reserve(max_count);
61 for (
auto it = m_listeners.begin(); it != m_listeners.end();) {
63 if (curr_listener_sp) {
64 if (it->second & event_mask)
65 listeners.emplace_back(std::move(curr_listener_sp), it->second);
69 it = m_listeners.erase(it);
71 if (include_primary && m_primary_listener_sp)
72 listeners.emplace_back(m_primary_listener_sp, m_primary_listener_mask);
78 if (m_primary_listener_sp)
80 for (
auto it = m_listeners.begin(); it != m_listeners.end(); it++) {
83 if (curr_listener_sp && (it->second & event_mask))
90 std::lock_guard<std::mutex> guard(m_listeners_mutex);
94 for (
auto &pair : GetListeners())
95 pair.first->BroadcasterWillDestruct(&m_broadcaster);
98 m_primary_listener_sp.reset();
102 return &m_broadcaster;
106 Stream &s, uint32_t event_mask,
bool prefix_with_broadcaster_name)
const {
107 uint32_t num_names_added = 0;
108 if (event_mask && !m_event_names.empty()) {
109 event_names_map::const_iterator end = m_event_names.end();
110 for (uint32_t
bit = 1u, mask = event_mask; mask != 0 &&
bit != 0;
111 bit <<= 1, mask >>= 1) {
113 event_names_map::const_iterator pos = m_event_names.find(
bit);
115 if (num_names_added > 0)
118 if (prefix_with_broadcaster_name) {
128 return num_names_added > 0;
136 uint32_t event_mask) {
140 std::lock_guard<std::mutex> guard(m_listeners_mutex);
144 bool handled =
false;
146 if (listener_sp == m_primary_listener_sp)
150 for (
auto &pair : GetListeners(
UINT32_MAX,
false)) {
151 if (pair.first == listener_sp) {
153 pair.second |= event_mask;
154 m_broadcaster.AddInitialEventsToListener(listener_sp, event_mask);
161 m_listeners.push_back(
166 m_broadcaster.AddInitialEventsToListener(listener_sp, event_mask);
174 std::lock_guard<std::mutex> guard(m_listeners_mutex);
176 if (!m_hijacking_listeners.empty() && event_type & m_hijacking_masks.back())
180 if (m_primary_listener_sp)
183 return HasListeners(event_type);
191 if (listener == m_primary_listener_sp.get()) {
194 m_primary_listener_sp.reset();
198 std::lock_guard<std::mutex> guard(m_listeners_mutex);
199 for (
auto it = m_listeners.begin(); it != m_listeners.end();) {
202 if (!curr_listener_sp) {
205 it = m_listeners.erase(it);
209 if (curr_listener_sp.get() == listener) {
210 it->second &= ~event_mask;
214 m_listeners.erase(it);
228 return PrivateBroadcastEvent(event_sp,
false);
232 return PrivateBroadcastEvent(event_sp,
true);
242 event_sp->SetBroadcaster(&m_broadcaster);
244 const uint32_t event_type = event_sp->GetType();
246 std::lock_guard<std::mutex> guard(m_listeners_mutex);
250 if (!m_hijacking_listeners.empty()) {
251 assert(!m_hijacking_masks.empty());
252 hijacking_listener_sp = m_hijacking_listeners.back();
253 if ((event_type & m_hijacking_masks.back()) == 0)
254 hijacking_listener_sp.reset();
258 if (!log && event_sp->GetData())
259 log = event_sp->GetData()->GetLogChannel();
263 event_sp->Dump(&event_description);
265 "{0:x} Broadcaster(\"{1}\")::BroadcastEvent (event_sp = {2}, "
266 "unique={3}) hijack = {4:x}",
268 event_description.
GetData(), unique,
269 static_cast<void *
>(hijacking_listener_sp.get()));
272 = hijacking_listener_sp ? hijacking_listener_sp : m_primary_listener_sp;
274 if (primary_listener_sp) {
275 if (unique && primary_listener_sp->PeekAtNextEventForBroadcasterWithType(
276 &m_broadcaster, event_type))
287 if (!hijacking_listener_sp) {
288 for (
auto &pair : GetListeners(event_type,
false))
289 event_sp->AddPendingListener(pair.first);
291 primary_listener_sp->AddEvent(event_sp);
293 for (
auto &pair : GetListeners(event_type)) {
294 if (unique && pair.first->PeekAtNextEventForBroadcasterWithType(
295 &m_broadcaster, event_type))
298 pair.first->AddEvent(event_sp);
304 auto event_sp = std::make_shared<Event>(event_type,
nullptr);
305 PrivateBroadcastEvent(event_sp,
false);
310 auto event_sp = std::make_shared<Event>(event_type, event_data_sp);
311 PrivateBroadcastEvent(event_sp,
false);
315 auto event_sp = std::make_shared<Event>(event_type,
nullptr);
316 PrivateBroadcastEvent(event_sp,
true);
324 m_primary_listener_sp = listener_sp;
330 std::lock_guard<std::mutex> guard(m_listeners_mutex);
335 "{0} Broadcaster(\"{1}\")::HijackBroadcaster (listener(\"{2}\")={3})",
337 listener_sp->m_name.c_str(),
static_cast<void *
>(listener_sp.get()));
338 m_hijacking_listeners.push_back(listener_sp);
339 m_hijacking_masks.push_back(event_mask);
344 std::lock_guard<std::mutex> guard(m_listeners_mutex);
346 if (!m_hijacking_listeners.empty())
347 return (event_mask & m_hijacking_masks.back()) != 0;
352 if (m_hijacking_listeners.size()) {
353 return m_hijacking_listeners.back()->GetName();
359 std::lock_guard<std::mutex> guard(m_listeners_mutex);
361 if (!m_hijacking_listeners.empty()) {
362 ListenerSP listener_sp = m_hijacking_listeners.back();
365 "{0} Broadcaster(\"{1}\")::RestoreBroadcaster (about to pop "
366 "listener(\"{2}\")={3})",
368 listener_sp->m_name.c_str(),
369 static_cast<void *
>(listener_sp.get()));
370 m_hijacking_listeners.pop_back();
372 if (!m_hijacking_masks.empty())
373 m_hijacking_masks.pop_back();
377 static constexpr llvm::StringLiteral class_name(
"lldb.anonymous");
400 return input.first.GetBroadcasterClass() ==
404 while (iter != end_iter &&
405 (iter = find_if(iter, end_iter, class_matches)) != end_iter) {
406 available_bits &= ~((*iter).first.GetEventBits());
410 if (available_bits != 0) {
417 return available_bits;
422 bool removed_some =
false;
427 auto listener_matches_and_shared_bits =
429 return input.first.GetBroadcasterClass() ==
431 (input.first.GetEventBits() & event_spec.
GetEventBits()) != 0 &&
432 input.second == listener_sp;
434 std::vector<BroadcastEventSpec> to_be_readded;
435 uint32_t event_bits_to_remove = event_spec.
GetEventBits();
440 iter = find_if(iter, end, listener_matches_and_shared_bits);
443 uint32_t iter_event_bits = (*iter).first.GetEventBits();
446 if (event_bits_to_remove != iter_event_bits) {
447 uint32_t new_event_bits = iter_event_bits & ~event_bits_to_remove;
455 for (
const auto &event : to_be_readded) {
466 auto event_spec_matches =
468 return input.first.IsContainedIn(event_spec);
471 auto iter = llvm::find_if(
m_event_map, event_spec_matches);
473 return (*iter).second;
480 auto listeners_predicate =
482 return input.get() == listener;
485 if (
auto iter = llvm::find_if(
m_listeners, listeners_predicate);
490 return input.second.get() == listener;
495 iter = find_if(iter, end, events_predicate);
506 auto listener_matches =
508 return input.second == listener_sp;
516 iter = find_if(iter, end_iter, listener_matches);
517 if (iter == end_iter)
531 return input.first.GetBroadcasterClass() ==
535 while (iter != end_iter &&
536 (iter = find_if(iter, end_iter, class_matches)) != end_iter) {
537 (*iter).second->StartListeningForEvents(&broadcaster,
538 (*iter).first.GetEventBits());
547 listener->BroadcasterManagerWillDestruct(this->shared_from_this());
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
bool operator<(const BroadcastEventSpec &rhs) const
uint32_t GetEventBits() const
const std::string & GetBroadcasterClass() const
listener_collection m_listeners
uint32_t RegisterListenerForEventsNoLock(const lldb::ListenerSP &listener_sp, const BroadcastEventSpec &event_spec)
static lldb::BroadcasterManagerSP MakeBroadcasterManager()
Listeners hold onto weak pointers to their broadcaster managers.
std::mutex m_manager_mutex
bool UnregisterListenerForEventsNoLock(const lldb::ListenerSP &listener_sp, const BroadcastEventSpec &event_spec)
void RemoveListener(const lldb::ListenerSP &listener_sp)
void SignUpListenersForBroadcaster(Broadcaster &broadcaster)
std::pair< BroadcastEventSpec, lldb::ListenerSP > event_listener_key
lldb::ListenerSP GetListenerForEventSpec(const BroadcastEventSpec &event_spec) const
BroadcasterImpl contains the actual Broadcaster implementation.
bool IsHijackedForEvent(uint32_t event_mask)
const char * GetHijackingListenerName()
void BroadcastEvent(lldb::EventSP &event_sp)
void SetPrimaryListener(lldb::ListenerSP listener_sp)
void PrivateBroadcastEvent(lldb::EventSP &event_sp, bool unique)
uint32_t AddListener(const lldb::ListenerSP &listener_sp, uint32_t event_mask)
void RestoreBroadcaster()
bool EventTypeHasListeners(uint32_t event_type)
llvm::SmallVector< std::pair< lldb::ListenerSP, uint32_t & >, 4 > GetListeners(uint32_t event_mask=UINT32_MAX, bool include_primary=true)
bool RemoveListener(lldb_private::Listener *listener, uint32_t event_mask=UINT32_MAX)
bool HasListeners(uint32_t event_mask)
bool GetEventNames(Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const
BroadcasterImpl(Broadcaster &broadcaster)
Broadcaster * GetBroadcaster()
bool HijackBroadcaster(const lldb::ListenerSP &listener_sp, uint32_t event_mask=UINT32_MAX)
void BroadcastEventIfUnique(lldb::EventSP &event_sp)
An event broadcasting class.
bool RemoveListener(const lldb::ListenerSP &listener_sp, uint32_t event_mask=UINT32_MAX)
Removes a Listener from this broadcasters list and frees the event bits specified by event_mask that ...
Broadcaster(lldb::BroadcasterManagerSP manager_sp, std::string name)
Construct with a broadcaster with a name.
virtual void AddInitialEventsToListener(const lldb::ListenerSP &listener_sp, uint32_t requested_events)
const std::string & GetBroadcasterName()
Get this broadcaster's name.
lldb::BroadcasterManagerSP m_manager_sp
virtual llvm::StringRef GetBroadcasterClass() const
This needs to be filled in if you are going to register the broadcaster with the broadcaster manager ...
void CheckInWithManager()
virtual ~Broadcaster()
Destructor.
const char * GetData() const
A stream class that can stream formatted output to a file.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::shared_ptr< lldb_private::BroadcasterManager > BroadcasterManagerSP
std::weak_ptr< lldb_private::Listener > ListenerWP
std::shared_ptr< lldb_private::Event > EventSP
std::shared_ptr< lldb_private::Listener > ListenerSP
std::shared_ptr< lldb_private::EventData > EventDataSP