Listener.cpp revision 360784
1238106Sdes//===-- Listener.cpp --------------------------------------------*- C++ -*-===//
2238106Sdes//
3238106Sdes// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4238106Sdes// See https://llvm.org/LICENSE.txt for license information.
5238106Sdes// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6238106Sdes//
7238106Sdes//===----------------------------------------------------------------------===//
8238106Sdes
9238106Sdes#include "lldb/Utility/Listener.h"
10238106Sdes
11238106Sdes#include "lldb/Utility/Broadcaster.h"
12238106Sdes#include "lldb/Utility/ConstString.h"
13238106Sdes#include "lldb/Utility/Event.h"
14238106Sdes#include "lldb/Utility/Log.h"
15238106Sdes#include "lldb/Utility/Logging.h"
16238106Sdes
17238106Sdes#include "llvm/ADT/Optional.h"
18238106Sdes
19238106Sdes#include <algorithm>
20238106Sdes#include <memory>
21238106Sdes#include <utility>
22238106Sdes
23238106Sdesusing namespace lldb;
24269257Sdesusing namespace lldb_private;
25269257Sdes
26269257Sdesnamespace {
27269257Sdesclass BroadcasterManagerWPMatcher {
28269257Sdespublic:
29269257Sdes  BroadcasterManagerWPMatcher(BroadcasterManagerSP manager_sp)
30269257Sdes      : m_manager_sp(std::move(manager_sp)) {}
31269257Sdes  bool operator()(const BroadcasterManagerWP &input_wp) const {
32269257Sdes    BroadcasterManagerSP input_sp = input_wp.lock();
33269257Sdes    return (input_sp && input_sp == m_manager_sp);
34238106Sdes  }
35238106Sdes
36238106Sdes  BroadcasterManagerSP m_manager_sp;
37238106Sdes};
38238106Sdes} // anonymous namespace
39238106Sdes
40238106SdesListener::Listener(const char *name)
41238106Sdes    : m_name(name), m_broadcasters(), m_broadcasters_mutex(), m_events(),
42238106Sdes      m_events_mutex() {
43238106Sdes  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
44238106Sdes  if (log != nullptr)
45238106Sdes    LLDB_LOGF(log, "%p Listener::Listener('%s')", static_cast<void *>(this),
46238106Sdes              m_name.c_str());
47238106Sdes}
48238106Sdes
49238106SdesListener::~Listener() {
50238106Sdes  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
51238106Sdes
52238106Sdes  Clear();
53238106Sdes
54269257Sdes  LLDB_LOGF(log, "%p Listener::%s('%s')", static_cast<void *>(this),
55238106Sdes            __FUNCTION__, m_name.c_str());
56238106Sdes}
57238106Sdes
58238106Sdesvoid Listener::Clear() {
59238106Sdes  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
60238106Sdes  std::lock_guard<std::recursive_mutex> broadcasters_guard(
61238106Sdes      m_broadcasters_mutex);
62238106Sdes  broadcaster_collection::iterator pos, end = m_broadcasters.end();
63238106Sdes  for (pos = m_broadcasters.begin(); pos != end; ++pos) {
64238106Sdes    Broadcaster::BroadcasterImplSP broadcaster_sp(pos->first.lock());
65238106Sdes    if (broadcaster_sp)
66238106Sdes      broadcaster_sp->RemoveListener(this, pos->second.event_mask);
67238106Sdes  }
68238106Sdes  m_broadcasters.clear();
69238106Sdes
70238106Sdes  std::lock_guard<std::mutex> events_guard(m_events_mutex);
71238106Sdes  m_events.clear();
72238106Sdes  size_t num_managers = m_broadcaster_managers.size();
73238106Sdes
74238106Sdes  for (size_t i = 0; i < num_managers; i++) {
75238106Sdes    BroadcasterManagerSP manager_sp(m_broadcaster_managers[i].lock());
76238106Sdes    if (manager_sp)
77238106Sdes      manager_sp->RemoveListener(this);
78238106Sdes  }
79238106Sdes
80238106Sdes  LLDB_LOGF(log, "%p Listener::%s('%s')", static_cast<void *>(this),
81238106Sdes            __FUNCTION__, m_name.c_str());
82238106Sdes}
83238106Sdes
84238106Sdesuint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster,
85238106Sdes                                           uint32_t event_mask) {
86238106Sdes  if (broadcaster) {
87238106Sdes    // Scope for "locker"
88238106Sdes    // Tell the broadcaster to add this object as a listener
89238106Sdes    {
90238106Sdes      std::lock_guard<std::recursive_mutex> broadcasters_guard(
91238106Sdes          m_broadcasters_mutex);
92238106Sdes      Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl());
93238106Sdes      m_broadcasters.insert(
94238106Sdes          std::make_pair(impl_wp, BroadcasterInfo(event_mask)));
95238106Sdes    }
96238106Sdes
97238106Sdes    uint32_t acquired_mask =
98238106Sdes        broadcaster->AddListener(this->shared_from_this(), event_mask);
99238106Sdes
100238106Sdes    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
101238106Sdes    if (log != nullptr)
102238106Sdes      LLDB_LOGF(log,
103238106Sdes                "%p Listener::StartListeningForEvents (broadcaster = %p, "
104238106Sdes                "mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s",
105238106Sdes                static_cast<void *>(this), static_cast<void *>(broadcaster),
106238106Sdes                event_mask, acquired_mask, m_name.c_str());
107238106Sdes
108238106Sdes    return acquired_mask;
109238106Sdes  }
110238106Sdes  return 0;
111238106Sdes}
112238106Sdes
113238106Sdesuint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster,
114238106Sdes                                           uint32_t event_mask,
115238106Sdes                                           HandleBroadcastCallback callback,
116238106Sdes                                           void *callback_user_data) {
117238106Sdes  if (broadcaster) {
118238106Sdes    // Scope for "locker"
119238106Sdes    // Tell the broadcaster to add this object as a listener
120238106Sdes    {
121238106Sdes      std::lock_guard<std::recursive_mutex> broadcasters_guard(
122238106Sdes          m_broadcasters_mutex);
123238106Sdes      Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl());
124238106Sdes      m_broadcasters.insert(std::make_pair(
125238106Sdes          impl_wp, BroadcasterInfo(event_mask, callback, callback_user_data)));
126238106Sdes    }
127238106Sdes
128238106Sdes    uint32_t acquired_mask =
129269257Sdes        broadcaster->AddListener(this->shared_from_this(), event_mask);
130238106Sdes
131238106Sdes    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
132238106Sdes    if (log != nullptr) {
133238106Sdes      void **pointer = reinterpret_cast<void **>(&callback);
134238106Sdes      LLDB_LOGF(log,
135238106Sdes                "%p Listener::StartListeningForEvents (broadcaster = %p, "
136238106Sdes                "mask = 0x%8.8x, callback = %p, user_data = %p) "
137238106Sdes                "acquired_mask = 0x%8.8x for %s",
138238106Sdes                static_cast<void *>(this), static_cast<void *>(broadcaster),
139238106Sdes                event_mask, *pointer, static_cast<void *>(callback_user_data),
140238106Sdes                acquired_mask, m_name.c_str());
141238106Sdes    }
142238106Sdes
143238106Sdes    return acquired_mask;
144238106Sdes  }
145238106Sdes  return 0;
146238106Sdes}
147238106Sdes
148238106Sdesbool Listener::StopListeningForEvents(Broadcaster *broadcaster,
149238106Sdes                                      uint32_t event_mask) {
150238106Sdes  if (broadcaster) {
151238106Sdes    // Scope for "locker"
152238106Sdes    {
153238106Sdes      std::lock_guard<std::recursive_mutex> broadcasters_guard(
154238106Sdes          m_broadcasters_mutex);
155238106Sdes      m_broadcasters.erase(broadcaster->GetBroadcasterImpl());
156238106Sdes    }
157238106Sdes    // Remove the broadcaster from our set of broadcasters
158238106Sdes    return broadcaster->RemoveListener(this->shared_from_this(), event_mask);
159238106Sdes  }
160238106Sdes
161238106Sdes  return false;
162238106Sdes}
163238106Sdes
164238106Sdes// Called when a Broadcaster is in its destructor. We need to remove all
165238106Sdes// knowledge of this broadcaster and any events that it may have queued up
166238106Sdesvoid Listener::BroadcasterWillDestruct(Broadcaster *broadcaster) {
167238106Sdes  // Scope for "broadcasters_locker"
168238106Sdes  {
169238106Sdes    std::lock_guard<std::recursive_mutex> broadcasters_guard(
170238106Sdes        m_broadcasters_mutex);
171238106Sdes    m_broadcasters.erase(broadcaster->GetBroadcasterImpl());
172238106Sdes  }
173238106Sdes
174238106Sdes  // Scope for "event_locker"
175238106Sdes  {
176238106Sdes    std::lock_guard<std::mutex> events_guard(m_events_mutex);
177238106Sdes    // Remove all events for this broadcaster object.
178238106Sdes    event_collection::iterator pos = m_events.begin();
179238106Sdes    while (pos != m_events.end()) {
180238106Sdes      if ((*pos)->GetBroadcaster() == broadcaster)
181238106Sdes        pos = m_events.erase(pos);
182238106Sdes      else
183238106Sdes        ++pos;
184238106Sdes    }
185238106Sdes  }
186238106Sdes}
187238106Sdes
188238106Sdesvoid Listener::BroadcasterManagerWillDestruct(BroadcasterManagerSP manager_sp) {
189238106Sdes  // Just need to remove this broadcast manager from the list of managers:
190238106Sdes  broadcaster_manager_collection::iterator iter,
191238106Sdes      end_iter = m_broadcaster_managers.end();
192238106Sdes  BroadcasterManagerWP manager_wp;
193238106Sdes
194238106Sdes  BroadcasterManagerWPMatcher matcher(std::move(manager_sp));
195238106Sdes  iter = std::find_if<broadcaster_manager_collection::iterator,
196238106Sdes                      BroadcasterManagerWPMatcher>(
197238106Sdes      m_broadcaster_managers.begin(), end_iter, matcher);
198238106Sdes  if (iter != end_iter)
199238106Sdes    m_broadcaster_managers.erase(iter);
200238106Sdes}
201238106Sdes
202238106Sdesvoid Listener::AddEvent(EventSP &event_sp) {
203238106Sdes  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
204238106Sdes  if (log != nullptr)
205238106Sdes    LLDB_LOGF(log, "%p Listener('%s')::AddEvent (event_sp = {%p})",
206238106Sdes              static_cast<void *>(this), m_name.c_str(),
207238106Sdes              static_cast<void *>(event_sp.get()));
208238106Sdes
209238106Sdes  std::lock_guard<std::mutex> guard(m_events_mutex);
210238106Sdes  m_events.push_back(event_sp);
211238106Sdes  m_events_condition.notify_all();
212238106Sdes}
213238106Sdes
214238106Sdesclass EventBroadcasterMatches {
215238106Sdespublic:
216238106Sdes  EventBroadcasterMatches(Broadcaster *broadcaster)
217238106Sdes      : m_broadcaster(broadcaster) {}
218238106Sdes
219238106Sdes  bool operator()(const EventSP &event_sp) const {
220238106Sdes    return event_sp->BroadcasterIs(m_broadcaster);
221238106Sdes  }
222238106Sdes
223269257Sdesprivate:
224238106Sdes  Broadcaster *m_broadcaster;
225238106Sdes};
226238106Sdes
227238106Sdesclass EventMatcher {
228238106Sdespublic:
229238106Sdes  EventMatcher(Broadcaster *broadcaster, const ConstString *broadcaster_names,
230238106Sdes               uint32_t num_broadcaster_names, uint32_t event_type_mask)
231238106Sdes      : m_broadcaster(broadcaster), m_broadcaster_names(broadcaster_names),
232238106Sdes        m_num_broadcaster_names(num_broadcaster_names),
233238106Sdes        m_event_type_mask(event_type_mask) {}
234238106Sdes
235238106Sdes  bool operator()(const EventSP &event_sp) const {
236238106Sdes    if (m_broadcaster && !event_sp->BroadcasterIs(m_broadcaster))
237238106Sdes      return false;
238238106Sdes
239269257Sdes    if (m_broadcaster_names) {
240238106Sdes      bool found_source = false;
241238106Sdes      ConstString event_broadcaster_name =
242238106Sdes          event_sp->GetBroadcaster()->GetBroadcasterName();
243238106Sdes      for (uint32_t i = 0; i < m_num_broadcaster_names; ++i) {
244238106Sdes        if (m_broadcaster_names[i] == event_broadcaster_name) {
245238106Sdes          found_source = true;
246238106Sdes          break;
247238106Sdes        }
248238106Sdes      }
249238106Sdes      if (!found_source)
250238106Sdes        return false;
251238106Sdes    }
252238106Sdes
253238106Sdes    return m_event_type_mask == 0 || m_event_type_mask & event_sp->GetType();
254238106Sdes  }
255238106Sdes
256238106Sdesprivate:
257238106Sdes  Broadcaster *m_broadcaster;
258238106Sdes  const ConstString *m_broadcaster_names;
259238106Sdes  const uint32_t m_num_broadcaster_names;
260238106Sdes  const uint32_t m_event_type_mask;
261238106Sdes};
262238106Sdes
263238106Sdesbool Listener::FindNextEventInternal(
264238106Sdes    std::unique_lock<std::mutex> &lock,
265238106Sdes    Broadcaster *broadcaster,             // nullptr for any broadcaster
266238106Sdes    const ConstString *broadcaster_names, // nullptr for any event
267238106Sdes    uint32_t num_broadcaster_names, uint32_t event_type_mask, EventSP &event_sp,
268238106Sdes    bool remove) {
269238106Sdes  // NOTE: callers of this function must lock m_events_mutex using a
270238106Sdes  // Mutex::Locker
271238106Sdes  // and pass the locker as the first argument. m_events_mutex is no longer
272238106Sdes  // recursive.
273238106Sdes  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
274238106Sdes
275238106Sdes  if (m_events.empty())
276238106Sdes    return false;
277238106Sdes
278238106Sdes  Listener::event_collection::iterator pos = m_events.end();
279238106Sdes
280238106Sdes  if (broadcaster == nullptr && broadcaster_names == nullptr &&
281238106Sdes      event_type_mask == 0) {
282238106Sdes    pos = m_events.begin();
283238106Sdes  } else {
284238106Sdes    pos = std::find_if(m_events.begin(), m_events.end(),
285238106Sdes                       EventMatcher(broadcaster, broadcaster_names,
286238106Sdes                                    num_broadcaster_names, event_type_mask));
287238106Sdes  }
288238106Sdes
289238106Sdes  if (pos != m_events.end()) {
290238106Sdes    event_sp = *pos;
291238106Sdes
292238106Sdes    if (log != nullptr)
293238106Sdes      LLDB_LOGF(log,
294238106Sdes                "%p '%s' Listener::FindNextEventInternal(broadcaster=%p, "
295238106Sdes                "broadcaster_names=%p[%u], event_type_mask=0x%8.8x, "
296238106Sdes                "remove=%i) event %p",
297238106Sdes                static_cast<void *>(this), GetName(),
298269257Sdes                static_cast<void *>(broadcaster),
299238106Sdes                static_cast<const void *>(broadcaster_names),
300238106Sdes                num_broadcaster_names, event_type_mask, remove,
301238106Sdes                static_cast<void *>(event_sp.get()));
302238106Sdes
303238106Sdes    if (remove) {
304238106Sdes      m_events.erase(pos);
305238106Sdes      // Unlock the event queue here.  We've removed this event and are about
306238106Sdes      // to return it so it should be okay to get the next event off the queue
307238106Sdes      // here - and it might be useful to do that in the "DoOnRemoval".
308238106Sdes      lock.unlock();
309238106Sdes      event_sp->DoOnRemoval();
310238106Sdes    }
311269257Sdes    return true;
312238106Sdes  }
313238106Sdes
314238106Sdes  event_sp.reset();
315238106Sdes  return false;
316238106Sdes}
317238106Sdes
318238106SdesEvent *Listener::PeekAtNextEvent() {
319238106Sdes  std::unique_lock<std::mutex> guard(m_events_mutex);
320238106Sdes  EventSP event_sp;
321238106Sdes  if (FindNextEventInternal(guard, nullptr, nullptr, 0, 0, event_sp, false))
322238106Sdes    return event_sp.get();
323238106Sdes  return nullptr;
324238106Sdes}
325238106Sdes
326238106SdesEvent *Listener::PeekAtNextEventForBroadcaster(Broadcaster *broadcaster) {
327238106Sdes  std::unique_lock<std::mutex> guard(m_events_mutex);
328238106Sdes  EventSP event_sp;
329238106Sdes  if (FindNextEventInternal(guard, broadcaster, nullptr, 0, 0, event_sp, false))
330238106Sdes    return event_sp.get();
331238106Sdes  return nullptr;
332238106Sdes}
333238106Sdes
334238106SdesEvent *
335238106SdesListener::PeekAtNextEventForBroadcasterWithType(Broadcaster *broadcaster,
336238106Sdes                                                uint32_t event_type_mask) {
337238106Sdes  std::unique_lock<std::mutex> guard(m_events_mutex);
338238106Sdes  EventSP event_sp;
339238106Sdes  if (FindNextEventInternal(guard, broadcaster, nullptr, 0, event_type_mask,
340238106Sdes                            event_sp, false))
341238106Sdes    return event_sp.get();
342238106Sdes  return nullptr;
343238106Sdes}
344238106Sdes
345238106Sdesbool Listener::GetEventInternal(
346238106Sdes    const Timeout<std::micro> &timeout,
347238106Sdes    Broadcaster *broadcaster,             // nullptr for any broadcaster
348238106Sdes    const ConstString *broadcaster_names, // nullptr for any event
349238106Sdes    uint32_t num_broadcaster_names, uint32_t event_type_mask,
350238106Sdes    EventSP &event_sp) {
351238106Sdes  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
352238106Sdes  LLDB_LOG(log, "this = {0}, timeout = {1} for {2}", this, timeout, m_name);
353238106Sdes
354238106Sdes  std::unique_lock<std::mutex> lock(m_events_mutex);
355238106Sdes
356285206Sdes  while (true) {
357238106Sdes    if (FindNextEventInternal(lock, broadcaster, broadcaster_names,
358238106Sdes                              num_broadcaster_names, event_type_mask, event_sp,
359238106Sdes                              true)) {
360238106Sdes      return true;
361238106Sdes    } else {
362285206Sdes      std::cv_status result = std::cv_status::no_timeout;
363238106Sdes      if (!timeout)
364238106Sdes        m_events_condition.wait(lock);
365238106Sdes      else
366238106Sdes        result = m_events_condition.wait_for(lock, *timeout);
367238106Sdes
368238106Sdes      if (result == std::cv_status::timeout) {
369238106Sdes        log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
370238106Sdes        LLDB_LOGF(log, "%p Listener::GetEventInternal() timed out for %s",
371238106Sdes                  static_cast<void *>(this), m_name.c_str());
372238106Sdes        return false;
373238106Sdes      } else if (result != std::cv_status::no_timeout) {
374238106Sdes        log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
375238106Sdes        LLDB_LOGF(log, "%p Listener::GetEventInternal() unknown error for %s",
376238106Sdes                  static_cast<void *>(this), m_name.c_str());
377238106Sdes        return false;
378238106Sdes      }
379238106Sdes    }
380238106Sdes  }
381238106Sdes
382238106Sdes  return false;
383238106Sdes}
384238106Sdes
385238106Sdesbool Listener::GetEventForBroadcasterWithType(
386238106Sdes    Broadcaster *broadcaster, uint32_t event_type_mask, EventSP &event_sp,
387238106Sdes    const Timeout<std::micro> &timeout) {
388238106Sdes  return GetEventInternal(timeout, broadcaster, nullptr, 0, event_type_mask,
389238106Sdes                          event_sp);
390238106Sdes}
391238106Sdes
392238106Sdesbool Listener::GetEventForBroadcaster(Broadcaster *broadcaster,
393238106Sdes                                      EventSP &event_sp,
394238106Sdes                                      const Timeout<std::micro> &timeout) {
395238106Sdes  return GetEventInternal(timeout, broadcaster, nullptr, 0, 0, event_sp);
396238106Sdes}
397238106Sdes
398238106Sdesbool Listener::GetEvent(EventSP &event_sp, const Timeout<std::micro> &timeout) {
399238106Sdes  return GetEventInternal(timeout, nullptr, nullptr, 0, 0, event_sp);
400238106Sdes}
401238106Sdes
402238106Sdessize_t Listener::HandleBroadcastEvent(EventSP &event_sp) {
403238106Sdes  size_t num_handled = 0;
404238106Sdes  std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
405238106Sdes  Broadcaster *broadcaster = event_sp->GetBroadcaster();
406238106Sdes  if (!broadcaster)
407238106Sdes    return 0;
408238106Sdes  broadcaster_collection::iterator pos;
409238106Sdes  broadcaster_collection::iterator end = m_broadcasters.end();
410285206Sdes  Broadcaster::BroadcasterImplSP broadcaster_impl_sp(
411285206Sdes      broadcaster->GetBroadcasterImpl());
412238106Sdes  for (pos = m_broadcasters.find(broadcaster_impl_sp);
413238106Sdes       pos != end && pos->first.lock() == broadcaster_impl_sp; ++pos) {
414238106Sdes    BroadcasterInfo info = pos->second;
415285206Sdes    if (event_sp->GetType() & info.event_mask) {
416238106Sdes      if (info.callback != nullptr) {
417238106Sdes        info.callback(event_sp, info.callback_user_data);
418238106Sdes        ++num_handled;
419238106Sdes      }
420238106Sdes    }
421238106Sdes  }
422238106Sdes  return num_handled;
423238106Sdes}
424238106Sdes
425238106Sdesuint32_t
426238106SdesListener::StartListeningForEventSpec(const BroadcasterManagerSP &manager_sp,
427238106Sdes                                     const BroadcastEventSpec &event_spec) {
428238106Sdes  if (!manager_sp)
429238106Sdes    return 0;
430238106Sdes
431238106Sdes  // The BroadcasterManager mutex must be locked before m_broadcasters_mutex to
432238106Sdes  // avoid violating the lock hierarchy (manager before broadcasters).
433238106Sdes  std::lock_guard<std::recursive_mutex> manager_guard(
434238106Sdes      manager_sp->m_manager_mutex);
435238106Sdes  std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
436238106Sdes
437238106Sdes  uint32_t bits_acquired = manager_sp->RegisterListenerForEvents(
438285206Sdes      this->shared_from_this(), event_spec);
439238106Sdes  if (bits_acquired) {
440238106Sdes    broadcaster_manager_collection::iterator iter,
441238106Sdes        end_iter = m_broadcaster_managers.end();
442285206Sdes    BroadcasterManagerWP manager_wp(manager_sp);
443238106Sdes    BroadcasterManagerWPMatcher matcher(manager_sp);
444238106Sdes    iter = std::find_if<broadcaster_manager_collection::iterator,
445238106Sdes                        BroadcasterManagerWPMatcher>(
446238106Sdes        m_broadcaster_managers.begin(), end_iter, matcher);
447238106Sdes    if (iter == end_iter)
448238106Sdes      m_broadcaster_managers.push_back(manager_wp);
449238106Sdes  }
450238106Sdes
451238106Sdes  return bits_acquired;
452238106Sdes}
453238106Sdes
454238106Sdesbool Listener::StopListeningForEventSpec(const BroadcasterManagerSP &manager_sp,
455238106Sdes                                         const BroadcastEventSpec &event_spec) {
456238106Sdes  if (!manager_sp)
457238106Sdes    return false;
458238106Sdes
459238106Sdes  std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
460238106Sdes  return manager_sp->UnregisterListenerForEvents(this->shared_from_this(),
461238106Sdes                                                 event_spec);
462238106Sdes}
463238106Sdes
464238106SdesListenerSP Listener::MakeListener(const char *name) {
465238106Sdes  return ListenerSP(new Listener(name));
466238106Sdes}
467238106Sdes