1254721Semaste//===-- Listener.cpp --------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Core/Listener.h"
11254721Semaste
12254721Semaste// C Includes
13254721Semaste// C++ Includes
14254721Semaste// Other libraries and framework includes
15254721Semaste// Project includes
16254721Semaste#include "lldb/Core/Broadcaster.h"
17254721Semaste#include "lldb/Core/Log.h"
18254721Semaste#include "lldb/Core/StreamString.h"
19254721Semaste#include "lldb/Core/Event.h"
20254721Semaste#include "lldb/Host/TimeValue.h"
21254721Semaste#include "lldb/lldb-private-log.h"
22254721Semaste#include <algorithm>
23254721Semaste
24254721Semasteusing namespace lldb;
25254721Semasteusing namespace lldb_private;
26254721Semaste
27254721SemasteListener::Listener(const char *name) :
28254721Semaste    m_name (name),
29254721Semaste    m_broadcasters(),
30254721Semaste    m_broadcasters_mutex (Mutex::eMutexTypeRecursive),
31254721Semaste    m_events (),
32254721Semaste    m_events_mutex (Mutex::eMutexTypeRecursive),
33254721Semaste    m_cond_wait()
34254721Semaste{
35254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
36254721Semaste    if (log)
37254721Semaste        log->Printf ("%p Listener::Listener('%s')", this, m_name.c_str());
38254721Semaste}
39254721Semaste
40254721SemasteListener::~Listener()
41254721Semaste{
42254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
43254721Semaste    Mutex::Locker locker (m_broadcasters_mutex);
44254721Semaste
45254721Semaste    size_t num_managers = m_broadcaster_managers.size();
46254721Semaste
47254721Semaste    for (size_t i = 0; i < num_managers; i++)
48254721Semaste        m_broadcaster_managers[i]->RemoveListener(*this);
49254721Semaste
50254721Semaste    if (log)
51254721Semaste        log->Printf ("%p Listener::~Listener('%s')", this, m_name.c_str());
52254721Semaste    Clear();
53254721Semaste}
54254721Semaste
55254721Semastevoid
56254721SemasteListener::Clear()
57254721Semaste{
58254721Semaste    Mutex::Locker locker(m_broadcasters_mutex);
59254721Semaste    broadcaster_collection::iterator pos, end = m_broadcasters.end();
60254721Semaste    for (pos = m_broadcasters.begin(); pos != end; ++pos)
61254721Semaste        pos->first->RemoveListener (this, pos->second.event_mask);
62254721Semaste    m_broadcasters.clear();
63254721Semaste    m_cond_wait.SetValue (false, eBroadcastNever);
64254721Semaste    m_broadcasters.clear();
65254721Semaste    Mutex::Locker event_locker(m_events_mutex);
66254721Semaste    m_events.clear();
67254721Semaste}
68254721Semaste
69254721Semasteuint32_t
70254721SemasteListener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask)
71254721Semaste{
72254721Semaste    if (broadcaster)
73254721Semaste    {
74254721Semaste        // Scope for "locker"
75254721Semaste        // Tell the broadcaster to add this object as a listener
76254721Semaste        {
77254721Semaste            Mutex::Locker locker(m_broadcasters_mutex);
78254721Semaste            m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask)));
79254721Semaste        }
80254721Semaste
81254721Semaste        uint32_t acquired_mask = broadcaster->AddListener (this, event_mask);
82254721Semaste
83254721Semaste        if (event_mask != acquired_mask)
84254721Semaste        {
85254721Semaste
86254721Semaste        }
87254721Semaste        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
88254721Semaste        if (log)
89254721Semaste            log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s",
90254721Semaste                         this,
91254721Semaste                         broadcaster,
92254721Semaste                         event_mask,
93254721Semaste                         acquired_mask,
94254721Semaste                         m_name.c_str());
95254721Semaste
96254721Semaste        return acquired_mask;
97254721Semaste
98254721Semaste    }
99254721Semaste    return 0;
100254721Semaste}
101254721Semaste
102254721Semasteuint32_t
103254721SemasteListener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask, HandleBroadcastCallback callback, void *callback_user_data)
104254721Semaste{
105254721Semaste    if (broadcaster)
106254721Semaste    {
107254721Semaste        // Scope for "locker"
108254721Semaste        // Tell the broadcaster to add this object as a listener
109254721Semaste        {
110254721Semaste            Mutex::Locker locker(m_broadcasters_mutex);
111254721Semaste            m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask, callback, callback_user_data)));
112254721Semaste        }
113254721Semaste
114254721Semaste        uint32_t acquired_mask = broadcaster->AddListener (this, event_mask);
115254721Semaste
116254721Semaste        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
117254721Semaste        if (log)
118254721Semaste            log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x, callback = %p, user_data = %p) acquired_mask = 0x%8.8x for %s",
119254721Semaste                        this, broadcaster, event_mask, callback, callback_user_data, acquired_mask, m_name.c_str());
120254721Semaste
121254721Semaste        return acquired_mask;
122254721Semaste    }
123254721Semaste    return 0;
124254721Semaste}
125254721Semaste
126254721Semastebool
127254721SemasteListener::StopListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask)
128254721Semaste{
129254721Semaste    if (broadcaster)
130254721Semaste    {
131254721Semaste        // Scope for "locker"
132254721Semaste        {
133254721Semaste            Mutex::Locker locker(m_broadcasters_mutex);
134254721Semaste            m_broadcasters.erase (broadcaster);
135254721Semaste        }
136254721Semaste        // Remove the broadcaster from our set of broadcasters
137254721Semaste        return broadcaster->RemoveListener (this, event_mask);
138254721Semaste    }
139254721Semaste
140254721Semaste    return false;
141254721Semaste}
142254721Semaste
143254721Semaste// Called when a Broadcaster is in its destuctor. We need to remove all
144254721Semaste// knowledge of this broadcaster and any events that it may have queued up
145254721Semastevoid
146254721SemasteListener::BroadcasterWillDestruct (Broadcaster *broadcaster)
147254721Semaste{
148254721Semaste    // Scope for "broadcasters_locker"
149254721Semaste    {
150254721Semaste        Mutex::Locker broadcasters_locker(m_broadcasters_mutex);
151254721Semaste        m_broadcasters.erase (broadcaster);
152254721Semaste    }
153254721Semaste
154254721Semaste    // Scope for "event_locker"
155254721Semaste    {
156254721Semaste        Mutex::Locker event_locker(m_events_mutex);
157254721Semaste        // Remove all events for this broadcaster object.
158254721Semaste        event_collection::iterator pos = m_events.begin();
159254721Semaste        while (pos != m_events.end())
160254721Semaste        {
161254721Semaste            if ((*pos)->GetBroadcaster() == broadcaster)
162254721Semaste                pos = m_events.erase(pos);
163254721Semaste            else
164254721Semaste                ++pos;
165254721Semaste        }
166254721Semaste
167254721Semaste        if (m_events.empty())
168254721Semaste            m_cond_wait.SetValue (false, eBroadcastNever);
169254721Semaste
170254721Semaste    }
171254721Semaste}
172254721Semaste
173254721Semastevoid
174254721SemasteListener::BroadcasterManagerWillDestruct (BroadcasterManager *manager)
175254721Semaste{
176254721Semaste    // Just need to remove this broadcast manager from the list of managers:
177254721Semaste    broadcaster_manager_collection::iterator iter, end_iter = m_broadcaster_managers.end();
178254721Semaste    iter = find(m_broadcaster_managers.begin(), end_iter, manager);
179254721Semaste    if (iter != end_iter)
180254721Semaste        m_broadcaster_managers.erase (iter);
181254721Semaste}
182254721Semaste
183254721Semastevoid
184254721SemasteListener::AddEvent (EventSP &event_sp)
185254721Semaste{
186254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
187254721Semaste    if (log)
188254721Semaste        log->Printf ("%p Listener('%s')::AddEvent (event_sp = {%p})", this, m_name.c_str(), event_sp.get());
189254721Semaste
190254721Semaste    // Scope for "locker"
191254721Semaste    {
192254721Semaste        Mutex::Locker locker(m_events_mutex);
193254721Semaste        m_events.push_back (event_sp);
194254721Semaste    }
195254721Semaste    m_cond_wait.SetValue (true, eBroadcastAlways);
196254721Semaste}
197254721Semaste
198254721Semasteclass EventBroadcasterMatches
199254721Semaste{
200254721Semastepublic:
201254721Semaste    EventBroadcasterMatches (Broadcaster *broadcaster) :
202254721Semaste        m_broadcaster (broadcaster)    {
203254721Semaste    }
204254721Semaste
205254721Semaste    bool operator() (const EventSP &event_sp) const
206254721Semaste    {
207254721Semaste        if (event_sp->BroadcasterIs(m_broadcaster))
208254721Semaste            return true;
209254721Semaste        else
210254721Semaste            return false;
211254721Semaste    }
212254721Semaste
213254721Semasteprivate:
214254721Semaste    Broadcaster *m_broadcaster;
215254721Semaste
216254721Semaste};
217254721Semaste
218254721Semasteclass EventMatcher
219254721Semaste{
220254721Semastepublic:
221254721Semaste    EventMatcher (Broadcaster *broadcaster, const ConstString *broadcaster_names, uint32_t num_broadcaster_names, uint32_t event_type_mask) :
222254721Semaste        m_broadcaster (broadcaster),
223254721Semaste        m_broadcaster_names (broadcaster_names),
224254721Semaste        m_num_broadcaster_names (num_broadcaster_names),
225254721Semaste        m_event_type_mask (event_type_mask)
226254721Semaste    {
227254721Semaste    }
228254721Semaste
229254721Semaste    bool operator() (const EventSP &event_sp) const
230254721Semaste    {
231254721Semaste        if (m_broadcaster && !event_sp->BroadcasterIs(m_broadcaster))
232254721Semaste            return false;
233254721Semaste
234254721Semaste        if (m_broadcaster_names)
235254721Semaste        {
236254721Semaste            bool found_source = false;
237254721Semaste            const ConstString &event_broadcaster_name = event_sp->GetBroadcaster()->GetBroadcasterName();
238254721Semaste            for (uint32_t i=0; i<m_num_broadcaster_names; ++i)
239254721Semaste            {
240254721Semaste                if (m_broadcaster_names[i] == event_broadcaster_name)
241254721Semaste                {
242254721Semaste                    found_source = true;
243254721Semaste                    break;
244254721Semaste                }
245254721Semaste            }
246254721Semaste            if (!found_source)
247254721Semaste                return false;
248254721Semaste        }
249254721Semaste
250254721Semaste        if (m_event_type_mask == 0 || m_event_type_mask & event_sp->GetType())
251254721Semaste            return true;
252254721Semaste        return false;
253254721Semaste    }
254254721Semaste
255254721Semasteprivate:
256254721Semaste    Broadcaster *m_broadcaster;
257254721Semaste    const ConstString *m_broadcaster_names;
258254721Semaste    const uint32_t m_num_broadcaster_names;
259254721Semaste    const uint32_t m_event_type_mask;
260254721Semaste};
261254721Semaste
262254721Semaste
263254721Semastebool
264254721SemasteListener::FindNextEventInternal
265254721Semaste(
266254721Semaste    Broadcaster *broadcaster,   // NULL for any broadcaster
267254721Semaste    const ConstString *broadcaster_names, // NULL for any event
268254721Semaste    uint32_t num_broadcaster_names,
269254721Semaste    uint32_t event_type_mask,
270254721Semaste    EventSP &event_sp,
271254721Semaste    bool remove)
272254721Semaste{
273254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
274254721Semaste
275254721Semaste    Mutex::Locker lock(m_events_mutex);
276254721Semaste
277254721Semaste    if (m_events.empty())
278254721Semaste        return false;
279254721Semaste
280254721Semaste
281254721Semaste    Listener::event_collection::iterator pos = m_events.end();
282254721Semaste
283254721Semaste    if (broadcaster == NULL && broadcaster_names == NULL && event_type_mask == 0)
284254721Semaste    {
285254721Semaste        pos = m_events.begin();
286254721Semaste    }
287254721Semaste    else
288254721Semaste    {
289254721Semaste        pos = std::find_if (m_events.begin(), m_events.end(), EventMatcher (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask));
290254721Semaste    }
291254721Semaste
292254721Semaste    if (pos != m_events.end())
293254721Semaste    {
294254721Semaste        event_sp = *pos;
295254721Semaste
296254721Semaste        if (log)
297254721Semaste            log->Printf ("%p '%s' Listener::FindNextEventInternal(broadcaster=%p, broadcaster_names=%p[%u], event_type_mask=0x%8.8x, remove=%i) event %p",
298254721Semaste                         this,
299254721Semaste                         GetName(),
300254721Semaste                         broadcaster,
301254721Semaste                         broadcaster_names,
302254721Semaste                         num_broadcaster_names,
303254721Semaste                         event_type_mask,
304254721Semaste                         remove,
305254721Semaste                         event_sp.get());
306254721Semaste
307254721Semaste        if (remove)
308254721Semaste        {
309254721Semaste            m_events.erase(pos);
310254721Semaste
311254721Semaste            if (m_events.empty())
312254721Semaste                m_cond_wait.SetValue (false, eBroadcastNever);
313254721Semaste        }
314254721Semaste
315254721Semaste        // Unlock the event queue here.  We've removed this event and are about to return
316254721Semaste        // it so it should be okay to get the next event off the queue here - and it might
317254721Semaste        // be useful to do that in the "DoOnRemoval".
318254721Semaste        lock.Unlock();
319254721Semaste
320254721Semaste        // Don't call DoOnRemoval if you aren't removing the event...
321254721Semaste        if (remove)
322254721Semaste            event_sp->DoOnRemoval();
323254721Semaste
324254721Semaste        return true;
325254721Semaste    }
326254721Semaste
327254721Semaste    event_sp.reset();
328254721Semaste    return false;
329254721Semaste}
330254721Semaste
331254721SemasteEvent *
332254721SemasteListener::PeekAtNextEvent ()
333254721Semaste{
334254721Semaste    EventSP event_sp;
335254721Semaste    if (FindNextEventInternal (NULL, NULL, 0, 0, event_sp, false))
336254721Semaste        return event_sp.get();
337254721Semaste    return NULL;
338254721Semaste}
339254721Semaste
340254721SemasteEvent *
341254721SemasteListener::PeekAtNextEventForBroadcaster (Broadcaster *broadcaster)
342254721Semaste{
343254721Semaste    EventSP event_sp;
344254721Semaste    if (FindNextEventInternal (broadcaster, NULL, 0, 0, event_sp, false))
345254721Semaste        return event_sp.get();
346254721Semaste    return NULL;
347254721Semaste}
348254721Semaste
349254721SemasteEvent *
350254721SemasteListener::PeekAtNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask)
351254721Semaste{
352254721Semaste    EventSP event_sp;
353254721Semaste    if (FindNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp, false))
354254721Semaste        return event_sp.get();
355254721Semaste    return NULL;
356254721Semaste}
357254721Semaste
358254721Semaste
359254721Semastebool
360254721SemasteListener::GetNextEventInternal
361254721Semaste(
362254721Semaste    Broadcaster *broadcaster,   // NULL for any broadcaster
363254721Semaste    const ConstString *broadcaster_names, // NULL for any event
364254721Semaste    uint32_t num_broadcaster_names,
365254721Semaste    uint32_t event_type_mask,
366254721Semaste    EventSP &event_sp
367254721Semaste)
368254721Semaste{
369254721Semaste    return FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true);
370254721Semaste}
371254721Semaste
372254721Semastebool
373254721SemasteListener::GetNextEvent (EventSP &event_sp)
374254721Semaste{
375254721Semaste    return GetNextEventInternal (NULL, NULL, 0, 0, event_sp);
376254721Semaste}
377254721Semaste
378254721Semaste
379254721Semastebool
380254721SemasteListener::GetNextEventForBroadcaster (Broadcaster *broadcaster, EventSP &event_sp)
381254721Semaste{
382254721Semaste    return GetNextEventInternal (broadcaster, NULL, 0, 0, event_sp);
383254721Semaste}
384254721Semaste
385254721Semastebool
386254721SemasteListener::GetNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask, EventSP &event_sp)
387254721Semaste{
388254721Semaste    return GetNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp);
389254721Semaste}
390254721Semaste
391254721Semaste
392254721Semastebool
393254721SemasteListener::WaitForEventsInternal
394254721Semaste(
395254721Semaste    const TimeValue *timeout,
396254721Semaste    Broadcaster *broadcaster,   // NULL for any broadcaster
397254721Semaste    const ConstString *broadcaster_names, // NULL for any event
398254721Semaste    uint32_t num_broadcaster_names,
399254721Semaste    uint32_t event_type_mask,
400254721Semaste    EventSP &event_sp
401254721Semaste)
402254721Semaste{
403254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
404254721Semaste    bool timed_out = false;
405254721Semaste
406254721Semaste    if (log)
407254721Semaste    {
408254721Semaste        log->Printf ("%p Listener::WaitForEventsInternal (timeout = { %p }) for %s",
409254721Semaste                    this, timeout, m_name.c_str());
410254721Semaste    }
411254721Semaste
412254721Semaste    while (1)
413254721Semaste    {
414254721Semaste        // Note, we don't want to lock the m_events_mutex in the call to GetNextEventInternal, since the DoOnRemoval
415254721Semaste        // code might require that new events be serviced.  For instance, the Breakpoint Command's
416254721Semaste        if (GetNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp))
417254721Semaste                return true;
418254721Semaste
419254721Semaste        {
420254721Semaste            // Reset condition value to false, so we can wait for new events to be
421254721Semaste            // added that might meet our current filter
422254721Semaste            // But first poll for any new event that might satisfy our condition, and if so consume it,
423254721Semaste            // otherwise wait.
424254721Semaste
425254721Semaste            Mutex::Locker event_locker(m_events_mutex);
426254721Semaste            const bool remove = false;
427254721Semaste            if (FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, remove))
428254721Semaste                continue;
429254721Semaste            else
430254721Semaste                m_cond_wait.SetValue (false, eBroadcastNever);
431254721Semaste        }
432254721Semaste
433254721Semaste        if (m_cond_wait.WaitForValueEqualTo (true, timeout, &timed_out))
434254721Semaste            continue;
435254721Semaste
436254721Semaste        else if (timed_out)
437254721Semaste        {
438254721Semaste            log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
439254721Semaste            if (log)
440254721Semaste                log->Printf ("%p Listener::WaitForEventsInternal() timed out for %s", this, m_name.c_str());
441254721Semaste            break;
442254721Semaste        }
443254721Semaste        else
444254721Semaste        {
445254721Semaste            log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
446254721Semaste            if (log)
447254721Semaste                log->Printf ("%p Listener::WaitForEventsInternal() unknown error for %s", this, m_name.c_str());
448254721Semaste            break;
449254721Semaste        }
450254721Semaste    }
451254721Semaste
452254721Semaste    return false;
453254721Semaste}
454254721Semaste
455254721Semastebool
456254721SemasteListener::WaitForEventForBroadcasterWithType
457254721Semaste(
458254721Semaste    const TimeValue *timeout,
459254721Semaste    Broadcaster *broadcaster,
460254721Semaste    uint32_t event_type_mask,
461254721Semaste    EventSP &event_sp
462254721Semaste)
463254721Semaste{
464254721Semaste    return WaitForEventsInternal (timeout, broadcaster, NULL, 0, event_type_mask, event_sp);
465254721Semaste}
466254721Semaste
467254721Semastebool
468254721SemasteListener::WaitForEventForBroadcaster
469254721Semaste(
470254721Semaste    const TimeValue *timeout,
471254721Semaste    Broadcaster *broadcaster,
472254721Semaste    EventSP &event_sp
473254721Semaste)
474254721Semaste{
475254721Semaste    return WaitForEventsInternal (timeout, broadcaster, NULL, 0, 0, event_sp);
476254721Semaste}
477254721Semaste
478254721Semastebool
479254721SemasteListener::WaitForEvent (const TimeValue *timeout, EventSP &event_sp)
480254721Semaste{
481254721Semaste    return WaitForEventsInternal (timeout, NULL, NULL, 0, 0, event_sp);
482254721Semaste}
483254721Semaste
484254721Semaste//Listener::broadcaster_collection::iterator
485254721Semaste//Listener::FindBroadcasterWithMask (Broadcaster *broadcaster, uint32_t event_mask, bool exact)
486254721Semaste//{
487254721Semaste//    broadcaster_collection::iterator pos;
488254721Semaste//    broadcaster_collection::iterator end = m_broadcasters.end();
489254721Semaste//    for (pos = m_broadcasters.find (broadcaster);
490254721Semaste//        pos != end && pos->first == broadcaster;
491254721Semaste//        ++pos)
492254721Semaste//    {
493254721Semaste//        if (exact)
494254721Semaste//        {
495254721Semaste//            if ((event_mask & pos->second.event_mask) == event_mask)
496254721Semaste//                return pos;
497254721Semaste//        }
498254721Semaste//        else
499254721Semaste//        {
500254721Semaste//            if (event_mask & pos->second.event_mask)
501254721Semaste//                return pos;
502254721Semaste//        }
503254721Semaste//    }
504254721Semaste//    return end;
505254721Semaste//}
506254721Semaste
507254721Semastesize_t
508254721SemasteListener::HandleBroadcastEvent (EventSP &event_sp)
509254721Semaste{
510254721Semaste    size_t num_handled = 0;
511254721Semaste    Mutex::Locker locker(m_broadcasters_mutex);
512254721Semaste    Broadcaster *broadcaster = event_sp->GetBroadcaster();
513254721Semaste    broadcaster_collection::iterator pos;
514254721Semaste    broadcaster_collection::iterator end = m_broadcasters.end();
515254721Semaste    for (pos = m_broadcasters.find (broadcaster);
516254721Semaste        pos != end && pos->first == broadcaster;
517254721Semaste        ++pos)
518254721Semaste    {
519254721Semaste        BroadcasterInfo info = pos->second;
520254721Semaste        if (event_sp->GetType () & info.event_mask)
521254721Semaste        {
522254721Semaste            if (info.callback != NULL)
523254721Semaste            {
524254721Semaste                info.callback (event_sp, info.callback_user_data);
525254721Semaste                ++num_handled;
526254721Semaste            }
527254721Semaste        }
528254721Semaste    }
529254721Semaste    return num_handled;
530254721Semaste}
531254721Semaste
532254721Semasteuint32_t
533254721SemasteListener::StartListeningForEventSpec (BroadcasterManager &manager,
534254721Semaste                             const BroadcastEventSpec &event_spec)
535254721Semaste{
536254721Semaste    // The BroadcasterManager mutex must be locked before m_broadcasters_mutex
537254721Semaste    // to avoid violating the lock hierarchy (manager before broadcasters).
538254721Semaste    Mutex::Locker manager_locker(manager.m_manager_mutex);
539254721Semaste    Mutex::Locker locker(m_broadcasters_mutex);
540254721Semaste
541254721Semaste    uint32_t bits_acquired = manager.RegisterListenerForEvents(*this, event_spec);
542254721Semaste    if (bits_acquired)
543254721Semaste        m_broadcaster_managers.push_back(&manager);
544254721Semaste
545254721Semaste    return bits_acquired;
546254721Semaste}
547254721Semaste
548254721Semastebool
549254721SemasteListener::StopListeningForEventSpec (BroadcasterManager &manager,
550254721Semaste                             const BroadcastEventSpec &event_spec)
551254721Semaste{
552254721Semaste    Mutex::Locker locker(m_broadcasters_mutex);
553254721Semaste    return manager.UnregisterListenerForEvents (*this, event_spec);
554254721Semaste
555254721Semaste}
556254721Semaste
557254721Semaste
558