1 //===-- Listener.cpp --------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Core/Listener.h"
14 // Other libraries and framework includes
16 #include "lldb/Core/Broadcaster.h"
17 #include "lldb/Core/Log.h"
18 #include "lldb/Core/StreamString.h"
19 #include "lldb/Core/Event.h"
20 #include "lldb/Host/TimeValue.h"
21 #include "lldb/lldb-private-log.h"
25 using namespace lldb_private;
27 Listener::Listener(const char *name) :
30 m_broadcasters_mutex (Mutex::eMutexTypeRecursive),
32 m_events_mutex (Mutex::eMutexTypeRecursive),
35 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
37 log->Printf ("%p Listener::Listener('%s')", this, m_name.c_str());
42 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
43 Mutex::Locker locker (m_broadcasters_mutex);
45 size_t num_managers = m_broadcaster_managers.size();
47 for (size_t i = 0; i < num_managers; i++)
48 m_broadcaster_managers[i]->RemoveListener(*this);
51 log->Printf ("%p Listener::~Listener('%s')", this, m_name.c_str());
58 Mutex::Locker locker(m_broadcasters_mutex);
59 broadcaster_collection::iterator pos, end = m_broadcasters.end();
60 for (pos = m_broadcasters.begin(); pos != end; ++pos)
61 pos->first->RemoveListener (this, pos->second.event_mask);
62 m_broadcasters.clear();
63 m_cond_wait.SetValue (false, eBroadcastNever);
64 m_broadcasters.clear();
65 Mutex::Locker event_locker(m_events_mutex);
70 Listener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask)
75 // Tell the broadcaster to add this object as a listener
77 Mutex::Locker locker(m_broadcasters_mutex);
78 m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask)));
81 uint32_t acquired_mask = broadcaster->AddListener (this, event_mask);
83 if (event_mask != acquired_mask)
87 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
89 log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s",
103 Listener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask, HandleBroadcastCallback callback, void *callback_user_data)
107 // Scope for "locker"
108 // Tell the broadcaster to add this object as a listener
110 Mutex::Locker locker(m_broadcasters_mutex);
111 m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask, callback, callback_user_data)));
114 uint32_t acquired_mask = broadcaster->AddListener (this, event_mask);
116 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
118 log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x, callback = %p, user_data = %p) acquired_mask = 0x%8.8x for %s",
119 this, broadcaster, event_mask, callback, callback_user_data, acquired_mask, m_name.c_str());
121 return acquired_mask;
127 Listener::StopListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask)
131 // Scope for "locker"
133 Mutex::Locker locker(m_broadcasters_mutex);
134 m_broadcasters.erase (broadcaster);
136 // Remove the broadcaster from our set of broadcasters
137 return broadcaster->RemoveListener (this, event_mask);
143 // Called when a Broadcaster is in its destuctor. We need to remove all
144 // knowledge of this broadcaster and any events that it may have queued up
146 Listener::BroadcasterWillDestruct (Broadcaster *broadcaster)
148 // Scope for "broadcasters_locker"
150 Mutex::Locker broadcasters_locker(m_broadcasters_mutex);
151 m_broadcasters.erase (broadcaster);
154 // Scope for "event_locker"
156 Mutex::Locker event_locker(m_events_mutex);
157 // Remove all events for this broadcaster object.
158 event_collection::iterator pos = m_events.begin();
159 while (pos != m_events.end())
161 if ((*pos)->GetBroadcaster() == broadcaster)
162 pos = m_events.erase(pos);
167 if (m_events.empty())
168 m_cond_wait.SetValue (false, eBroadcastNever);
174 Listener::BroadcasterManagerWillDestruct (BroadcasterManager *manager)
176 // Just need to remove this broadcast manager from the list of managers:
177 broadcaster_manager_collection::iterator iter, end_iter = m_broadcaster_managers.end();
178 iter = find(m_broadcaster_managers.begin(), end_iter, manager);
179 if (iter != end_iter)
180 m_broadcaster_managers.erase (iter);
184 Listener::AddEvent (EventSP &event_sp)
186 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
188 log->Printf ("%p Listener('%s')::AddEvent (event_sp = {%p})", this, m_name.c_str(), event_sp.get());
190 // Scope for "locker"
192 Mutex::Locker locker(m_events_mutex);
193 m_events.push_back (event_sp);
195 m_cond_wait.SetValue (true, eBroadcastAlways);
198 class EventBroadcasterMatches
201 EventBroadcasterMatches (Broadcaster *broadcaster) :
202 m_broadcaster (broadcaster) {
205 bool operator() (const EventSP &event_sp) const
207 if (event_sp->BroadcasterIs(m_broadcaster))
214 Broadcaster *m_broadcaster;
221 EventMatcher (Broadcaster *broadcaster, const ConstString *broadcaster_names, uint32_t num_broadcaster_names, uint32_t event_type_mask) :
222 m_broadcaster (broadcaster),
223 m_broadcaster_names (broadcaster_names),
224 m_num_broadcaster_names (num_broadcaster_names),
225 m_event_type_mask (event_type_mask)
229 bool operator() (const EventSP &event_sp) const
231 if (m_broadcaster && !event_sp->BroadcasterIs(m_broadcaster))
234 if (m_broadcaster_names)
236 bool found_source = false;
237 const ConstString &event_broadcaster_name = event_sp->GetBroadcaster()->GetBroadcasterName();
238 for (uint32_t i=0; i<m_num_broadcaster_names; ++i)
240 if (m_broadcaster_names[i] == event_broadcaster_name)
250 if (m_event_type_mask == 0 || m_event_type_mask & event_sp->GetType())
256 Broadcaster *m_broadcaster;
257 const ConstString *m_broadcaster_names;
258 const uint32_t m_num_broadcaster_names;
259 const uint32_t m_event_type_mask;
264 Listener::FindNextEventInternal
266 Broadcaster *broadcaster, // NULL for any broadcaster
267 const ConstString *broadcaster_names, // NULL for any event
268 uint32_t num_broadcaster_names,
269 uint32_t event_type_mask,
273 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
275 Mutex::Locker lock(m_events_mutex);
277 if (m_events.empty())
281 Listener::event_collection::iterator pos = m_events.end();
283 if (broadcaster == NULL && broadcaster_names == NULL && event_type_mask == 0)
285 pos = m_events.begin();
289 pos = std::find_if (m_events.begin(), m_events.end(), EventMatcher (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask));
292 if (pos != m_events.end())
297 log->Printf ("%p '%s' Listener::FindNextEventInternal(broadcaster=%p, broadcaster_names=%p[%u], event_type_mask=0x%8.8x, remove=%i) event %p",
302 num_broadcaster_names,
311 if (m_events.empty())
312 m_cond_wait.SetValue (false, eBroadcastNever);
315 // Unlock the event queue here. We've removed this event and are about to return
316 // it so it should be okay to get the next event off the queue here - and it might
317 // be useful to do that in the "DoOnRemoval".
320 // Don't call DoOnRemoval if you aren't removing the event...
322 event_sp->DoOnRemoval();
332 Listener::PeekAtNextEvent ()
335 if (FindNextEventInternal (NULL, NULL, 0, 0, event_sp, false))
336 return event_sp.get();
341 Listener::PeekAtNextEventForBroadcaster (Broadcaster *broadcaster)
344 if (FindNextEventInternal (broadcaster, NULL, 0, 0, event_sp, false))
345 return event_sp.get();
350 Listener::PeekAtNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask)
353 if (FindNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp, false))
354 return event_sp.get();
360 Listener::GetNextEventInternal
362 Broadcaster *broadcaster, // NULL for any broadcaster
363 const ConstString *broadcaster_names, // NULL for any event
364 uint32_t num_broadcaster_names,
365 uint32_t event_type_mask,
369 return FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true);
373 Listener::GetNextEvent (EventSP &event_sp)
375 return GetNextEventInternal (NULL, NULL, 0, 0, event_sp);
380 Listener::GetNextEventForBroadcaster (Broadcaster *broadcaster, EventSP &event_sp)
382 return GetNextEventInternal (broadcaster, NULL, 0, 0, event_sp);
386 Listener::GetNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask, EventSP &event_sp)
388 return GetNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp);
393 Listener::WaitForEventsInternal
395 const TimeValue *timeout,
396 Broadcaster *broadcaster, // NULL for any broadcaster
397 const ConstString *broadcaster_names, // NULL for any event
398 uint32_t num_broadcaster_names,
399 uint32_t event_type_mask,
403 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
404 bool timed_out = false;
408 log->Printf ("%p Listener::WaitForEventsInternal (timeout = { %p }) for %s",
409 this, timeout, m_name.c_str());
414 // Note, we don't want to lock the m_events_mutex in the call to GetNextEventInternal, since the DoOnRemoval
415 // code might require that new events be serviced. For instance, the Breakpoint Command's
416 if (GetNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp))
420 // Reset condition value to false, so we can wait for new events to be
421 // added that might meet our current filter
422 // But first poll for any new event that might satisfy our condition, and if so consume it,
425 Mutex::Locker event_locker(m_events_mutex);
426 const bool remove = false;
427 if (FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, remove))
430 m_cond_wait.SetValue (false, eBroadcastNever);
433 if (m_cond_wait.WaitForValueEqualTo (true, timeout, &timed_out))
438 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
440 log->Printf ("%p Listener::WaitForEventsInternal() timed out for %s", this, m_name.c_str());
445 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
447 log->Printf ("%p Listener::WaitForEventsInternal() unknown error for %s", this, m_name.c_str());
456 Listener::WaitForEventForBroadcasterWithType
458 const TimeValue *timeout,
459 Broadcaster *broadcaster,
460 uint32_t event_type_mask,
464 return WaitForEventsInternal (timeout, broadcaster, NULL, 0, event_type_mask, event_sp);
468 Listener::WaitForEventForBroadcaster
470 const TimeValue *timeout,
471 Broadcaster *broadcaster,
475 return WaitForEventsInternal (timeout, broadcaster, NULL, 0, 0, event_sp);
479 Listener::WaitForEvent (const TimeValue *timeout, EventSP &event_sp)
481 return WaitForEventsInternal (timeout, NULL, NULL, 0, 0, event_sp);
484 //Listener::broadcaster_collection::iterator
485 //Listener::FindBroadcasterWithMask (Broadcaster *broadcaster, uint32_t event_mask, bool exact)
487 // broadcaster_collection::iterator pos;
488 // broadcaster_collection::iterator end = m_broadcasters.end();
489 // for (pos = m_broadcasters.find (broadcaster);
490 // pos != end && pos->first == broadcaster;
495 // if ((event_mask & pos->second.event_mask) == event_mask)
500 // if (event_mask & pos->second.event_mask)
508 Listener::HandleBroadcastEvent (EventSP &event_sp)
510 size_t num_handled = 0;
511 Mutex::Locker locker(m_broadcasters_mutex);
512 Broadcaster *broadcaster = event_sp->GetBroadcaster();
513 broadcaster_collection::iterator pos;
514 broadcaster_collection::iterator end = m_broadcasters.end();
515 for (pos = m_broadcasters.find (broadcaster);
516 pos != end && pos->first == broadcaster;
519 BroadcasterInfo info = pos->second;
520 if (event_sp->GetType () & info.event_mask)
522 if (info.callback != NULL)
524 info.callback (event_sp, info.callback_user_data);
533 Listener::StartListeningForEventSpec (BroadcasterManager &manager,
534 const BroadcastEventSpec &event_spec)
536 // The BroadcasterManager mutex must be locked before m_broadcasters_mutex
537 // to avoid violating the lock hierarchy (manager before broadcasters).
538 Mutex::Locker manager_locker(manager.m_manager_mutex);
539 Mutex::Locker locker(m_broadcasters_mutex);
541 uint32_t bits_acquired = manager.RegisterListenerForEvents(*this, event_spec);
543 m_broadcaster_managers.push_back(&manager);
545 return bits_acquired;
549 Listener::StopListeningForEventSpec (BroadcasterManager &manager,
550 const BroadcastEventSpec &event_spec)
552 Mutex::Locker locker(m_broadcasters_mutex);
553 return manager.UnregisterListenerForEvents (*this, event_spec);