124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Broadcaster.cpp -----------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Broadcaster.h"
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Log.h"
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Event.h"
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/StreamString.h"
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private-log.h"
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
245a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcaster::Broadcaster (BroadcasterManager *manager, const char *name) :
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_broadcaster_name (name),
2649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    m_listeners (),
2749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    m_listeners_mutex (Mutex::eMutexTypeRecursive),
28b0cb717846f1b732245c402864987a106dfd28acJim Ingham    m_hijacking_listeners(),
295a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    m_hijacking_masks(),
305a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    m_manager (manager)
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
32952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (log)
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        log->Printf ("%p Broadcaster::Broadcaster(\"%s\")", this, m_broadcaster_name.AsCString());
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::~Broadcaster()
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
40952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (log)
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        log->Printf ("%p Broadcaster::~Broadcaster(\"%s\")", this, m_broadcaster_name.AsCString());
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
442f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton    Clear();
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
472f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Claytonvoid
485a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcaster::CheckInWithManager ()
495a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
505a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    if (m_manager != NULL)
515a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    {
525a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        m_manager->SignUpListenersForBroadcaster(*this);
535a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    }
545a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
555a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
565a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamvoid
572f57db09a49f2a05a620b8163bbe1e748a46ec73Greg ClaytonBroadcaster::Clear()
582f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton{
592f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton    Mutex::Locker listeners_locker(m_listeners_mutex);
602f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton
612f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton    // Make sure the listener forgets about this broadcaster. We do
622f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton    // this in the broadcaster in case the broadcaster object initiates
632f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton    // the removal.
642f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton
652f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton    collection::iterator pos, end = m_listeners.end();
662f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton    for (pos = m_listeners.begin(); pos != end; ++pos)
672f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton        pos->first->BroadcasterWillDestruct (this);
682f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton
692f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton    m_listeners.clear();
702f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton}
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst ConstString &
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::GetBroadcasterName ()
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_broadcaster_name;
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Claytonbool
7849ce682dfa7993d31206cea19ce7006cd3f3077eGreg ClaytonBroadcaster::GetEventNames (Stream &s, uint32_t event_mask, bool prefix_with_broadcaster_name) const
7949ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton{
8049ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    uint32_t num_names_added = 0;
8149ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    if (event_mask && !m_event_names.empty())
8249ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    {
8349ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton        event_names_map::const_iterator end = m_event_names.end();
8449ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton        for (uint32_t bit=1u, mask=event_mask; mask != 0 && bit != 0; bit <<= 1, mask >>= 1)
8549ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton        {
8649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton            if (mask & 1)
8749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton            {
8849ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                event_names_map::const_iterator pos = m_event_names.find(bit);
8949ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                if (pos != end)
9049ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                {
9149ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                    if (num_names_added > 0)
9249ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                        s.PutCString(", ");
9349ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton
9449ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                    if (prefix_with_broadcaster_name)
9549ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                    {
9649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                        s.PutCString (m_broadcaster_name.GetCString());
9749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                        s.PutChar('.');
9849ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                    }
9949ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                    s.PutCString(pos->second.c_str());
10049ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                    ++num_names_added;
10149ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                }
10249ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton            }
10349ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton        }
10449ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    }
10549ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    return num_names_added > 0;
10649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton}
10749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::AddInitialEventsToListener (Listener *listener, uint32_t requested_events)
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::AddListener (Listener* listener, uint32_t event_mask)
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
117e5001f50d6978b15e6957c1834412256054edafaJohnny Chen    if (listener == NULL)
118e5001f50d6978b15e6957c1834412256054edafaJohnny Chen        return 0;
119e5001f50d6978b15e6957c1834412256054edafaJohnny Chen
12049ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    Mutex::Locker locker(m_listeners_mutex);
12149ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    collection::iterator pos, end = m_listeners.end();
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    collection::iterator existing_pos = end;
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // See if we already have this listener, and if so, update its mask
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t taken_event_types = 0;
12649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    for (pos = m_listeners.begin(); pos != end; ++pos)
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (pos->first == listener)
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            existing_pos = pos;
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // For now don't descriminate on who gets what
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // FIXME: Implement "unique listener for this bit" mask
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //  taken_event_types |= pos->second;
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Each event bit in a Broadcaster object can only be used
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // by one listener
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t available_event_types = ~taken_event_types & event_mask;
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (available_event_types)
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // If we didn't find our listener, add it
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (existing_pos == end)
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Grant a new listener the available event bits
14549ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton            m_listeners.push_back(std::make_pair(listener, available_event_types));
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Grant the existing listener the available event bits
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            existing_pos->second |= available_event_types;
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Individual broadcasters decide whether they have outstanding data when a
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // listener attaches, and insert it into the listener with this method.
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        AddInitialEventsToListener (listener, available_event_types);
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Return the event bits that were granted to the listener
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return available_event_types;
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::EventTypeHasListeners (uint32_t event_type)
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
16649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    Mutex::Locker locker (m_listeners_mutex);
16763e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham
168b0cb717846f1b732245c402864987a106dfd28acJim Ingham    if (m_hijacking_listeners.size() > 0 && event_type & m_hijacking_masks.back())
16963e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham        return true;
17063e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham
17149ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    if (m_listeners.empty())
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17449ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    collection::iterator pos, end = m_listeners.end();
17549ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    for (pos = m_listeners.begin(); pos != end; ++pos)
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (pos->second & event_type)
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return true;
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::RemoveListener (Listener* listener, uint32_t event_mask)
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
18649ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    Mutex::Locker locker(m_listeners_mutex);
18749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    collection::iterator pos, end = m_listeners.end();
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // See if we already have this listener, and if so, update its mask
18949ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    for (pos = m_listeners.begin(); pos != end; ++pos)
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (pos->first == listener)
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Relinquish all event bits in "event_mask"
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            pos->second &= ~event_mask;
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // If all bits have been relinquished then remove this listener
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (pos->second == 0)
19749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton                m_listeners.erase (pos);
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return true;
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::BroadcastEvent (EventSP &event_sp)
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return PrivateBroadcastEvent (event_sp, false);
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::BroadcastEventIfUnique (EventSP &event_sp)
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return PrivateBroadcastEvent (event_sp, true);
21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Can't add a NULL event...
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (event_sp.get() == NULL)
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return;
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Update the broadcaster on this event
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    event_sp->SetBroadcaster (this);
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t event_type = event_sp->GetType();
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2286ae318c875fac58fb2d952739ee554c5ba18368fJim Ingham    Mutex::Locker event_types_locker(m_listeners_mutex);
229a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton
230a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton    Listener *hijacking_listener = NULL;
231a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton    if (!m_hijacking_listeners.empty())
232a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton    {
233a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton        assert (!m_hijacking_masks.empty());
234a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton        hijacking_listener = m_hijacking_listeners.back();
235a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton        if ((event_type & m_hijacking_masks.back()) == 0)
236a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton            hijacking_listener = NULL;
237a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton    }
238a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton
239952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (log)
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        StreamString event_description;
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        event_sp->Dump  (&event_description);
2446ae318c875fac58fb2d952739ee554c5ba18368fJim Ingham        log->Printf ("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, unique =%i) hijack = %p",
24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                     this,
24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                     m_broadcaster_name.AsCString(""),
24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                     event_description.GetData(),
2486ae318c875fac58fb2d952739ee554c5ba18368fJim Ingham                     unique,
249a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton                     hijacking_listener);
25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
252a118f0cbbe9441628715d24db5acd351ba5a0178Greg Clayton    if (hijacking_listener)
25363e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham    {
254b0cb717846f1b732245c402864987a106dfd28acJim Ingham        if (unique && hijacking_listener->PeekAtNextEventForBroadcasterWithType (this, event_type))
25563e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham            return;
256b0cb717846f1b732245c402864987a106dfd28acJim Ingham        hijacking_listener->AddEvent (event_sp);
25763e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham    }
25863e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham    else
25963e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham    {
26049ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton        collection::iterator pos, end = m_listeners.end();
26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26363e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham        // Iterate through all listener/mask pairs
26449ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton        for (pos = m_listeners.begin(); pos != end; ++pos)
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
26663e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham            // If the listener's mask matches any bits that we just set, then
26763e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham            // put the new event on its event queue.
26863e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham            if (event_type & pos->second)
26963e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham            {
27063e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham                if (unique && pos->first->PeekAtNextEventForBroadcasterWithType (this, event_type))
27163e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham                    continue;
27263e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham                pos->first->AddEvent (event_sp);
27363e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham            }
27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::BroadcastEvent (uint32_t event_type, EventData *event_data)
28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EventSP event_sp (new Event (event_type, event_data));
28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    PrivateBroadcastEvent (event_sp, false);
28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerBroadcaster::BroadcastEventIfUnique (uint32_t event_type, EventData *event_data)
28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EventSP event_sp (new Event (event_type, event_data));
28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    PrivateBroadcastEvent (event_sp, true);
29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
29263e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Inghambool
29363e24d7aeae8a7feb2aae0581e597b922749d4a1Jim InghamBroadcaster::HijackBroadcaster (Listener *listener, uint32_t event_mask)
29463e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham{
29549ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    Mutex::Locker event_types_locker(m_listeners_mutex);
2966ae318c875fac58fb2d952739ee554c5ba18368fJim Ingham
297952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
298b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen    if (log)
299b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen    {
300b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen        log->Printf ("%p Broadcaster(\"%s\")::HijackBroadcaster (listener(\"%s\")=%p)",
301b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen                     this,
302b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen                     m_broadcaster_name.AsCString(""),
303b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen                     listener->m_name.c_str(),
304b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen                     listener);
305b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen    }
306b0cb717846f1b732245c402864987a106dfd28acJim Ingham    m_hijacking_listeners.push_back(listener);
307b0cb717846f1b732245c402864987a106dfd28acJim Ingham    m_hijacking_masks.push_back(event_mask);
30863e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham    return true;
30963e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham}
31063e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham
31163e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Inghamvoid
31263e24d7aeae8a7feb2aae0581e597b922749d4a1Jim InghamBroadcaster::RestoreBroadcaster ()
31363e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham{
31449ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton    Mutex::Locker event_types_locker(m_listeners_mutex);
315b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen
316952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
317b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen    if (log)
318b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen    {
319b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen        Listener *listener = m_hijacking_listeners.back();
320b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen        log->Printf ("%p Broadcaster(\"%s\")::RestoreBroadcaster (about to pop listener(\"%s\")=%p)",
321b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen                     this,
322b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen                     m_broadcaster_name.AsCString(""),
323b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen                     listener->m_name.c_str(),
324b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen                     listener);
325b6641ba5fa6fd7c41f32cabc3ba94db1bc46c465Johnny Chen    }
326b0cb717846f1b732245c402864987a106dfd28acJim Ingham    m_hijacking_listeners.pop_back();
327b0cb717846f1b732245c402864987a106dfd28acJim Ingham    m_hijacking_masks.pop_back();
32863e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham}
32963e24d7aeae8a7feb2aae0581e597b922749d4a1Jim Ingham
3305a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamConstString &
3315a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcaster::GetBroadcasterClass() const
3325a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
3335a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    static ConstString class_name ("lldb.anonymous");
3345a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    return class_name;
3355a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
3365a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
3375a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcastEventSpec::BroadcastEventSpec (const BroadcastEventSpec &rhs) :
3385a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    m_broadcaster_class (rhs.m_broadcaster_class),
3395a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    m_event_bits (rhs.m_event_bits)
3405a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
3415a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
3425a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
3435a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghambool
3445a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcastEventSpec::operator< (const BroadcastEventSpec &rhs) const
3455a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
3465a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    if (GetBroadcasterClass() == rhs.GetBroadcasterClass())
3475a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    {
3485a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        return GetEventBits() < rhs.GetEventBits();
3495a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    }
3505a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    else
3515a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    {
3525a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        return GetBroadcasterClass() < rhs.GetBroadcasterClass();
3535a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    }
3545a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
3555a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
3565a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamconst BroadcastEventSpec &
3575a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcastEventSpec::operator= (const BroadcastEventSpec &rhs)
3585a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
3595a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    m_broadcaster_class = rhs.m_broadcaster_class;
3605a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    m_event_bits = rhs.m_event_bits;
3615a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    return *this;
3625a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
3635a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
3645a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::BroadcasterManager() :
3655a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    m_manager_mutex(Mutex::eMutexTypeRecursive)
3665a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
3675a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
3685a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
3695a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
3705a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamuint32_t
3715a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::RegisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec)
3725a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
3735a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    Mutex::Locker locker(m_manager_mutex);
3745a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
3755a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    collection::iterator iter = m_event_map.begin(), end_iter = m_event_map.end();
3765a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    uint32_t available_bits = event_spec.GetEventBits();
3775a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
3785a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    while (iter != end_iter
3795a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham           && (iter = find_if (iter, end_iter, BroadcasterClassMatches(event_spec.GetBroadcasterClass()))) != end_iter)
3805a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    {
3815a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        available_bits &= ~((*iter).first.GetEventBits());
3825a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        iter++;
3835a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    }
3845a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
3855a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    if (available_bits != 0)
3865a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    {
3875a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        m_event_map.insert (event_listener_key (BroadcastEventSpec (event_spec.GetBroadcasterClass(), available_bits), &listener));
3885a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        m_listeners.insert(&listener);
3895a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    }
3905a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
3915a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    return available_bits;
3925a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
3935a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
3945a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghambool
3955a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::UnregisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec)
3965a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
3975a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    Mutex::Locker locker(m_manager_mutex);
3985a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    bool removed_some = false;
3995a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4005a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    if (m_listeners.erase(&listener) == 0)
4015a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        return false;
4025a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4035a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    ListenerMatchesAndSharedBits predicate (event_spec, listener);
4045a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    std::vector<BroadcastEventSpec> to_be_readded;
4055a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    uint32_t event_bits_to_remove = event_spec.GetEventBits();
4065a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4075a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    // Go through the map and delete the exact matches, and build a list of matches that weren't exact to re-add:
4085a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    while (1)
4095a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    {
4105a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        collection::iterator iter, end_iter = m_event_map.end();
4115a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        iter = find_if (m_event_map.begin(), end_iter, predicate);
4125a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        if (iter == end_iter)
4135a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        {
4145a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham            break;
4155a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        }
4165a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        else
4175a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        {
4185a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham            uint32_t iter_event_bits = (*iter).first.GetEventBits();
4195a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham            removed_some = true;
4205a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4215a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham            if (event_bits_to_remove != iter_event_bits)
4225a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham            {
4235a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham                uint32_t new_event_bits = iter_event_bits & ~event_bits_to_remove;
4245a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham                to_be_readded.push_back(BroadcastEventSpec (event_spec.GetBroadcasterClass(), new_event_bits));
4255a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham            }
4265a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham            m_event_map.erase (iter);
4275a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        }
4285a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    }
4295a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4305a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    // Okay now add back the bits that weren't completely removed:
4315a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    for (size_t i = 0; i < to_be_readded.size(); i++)
4325a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    {
4335a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        m_event_map.insert (event_listener_key (to_be_readded[i], &listener));
4345a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    }
4355a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4365a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    return removed_some;
4375a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
4385a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4395a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamListener *
4405a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::GetListenerForEventSpec (BroadcastEventSpec event_spec) const
4415a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
4425a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    Mutex::Locker locker(*(const_cast<Mutex *> (&m_manager_mutex)));
4435a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4445a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    collection::const_iterator iter, end_iter = m_event_map.end();
4455a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    iter = find_if (m_event_map.begin(), end_iter, BroadcastEventSpecMatches (event_spec));
4465a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    if (iter != end_iter)
4475a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        return (*iter).second;
4485a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    else
4495a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        return NULL;
4505a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
4515a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4525a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamvoid
4535a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::RemoveListener (Listener &listener)
4545a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
4555a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    Mutex::Locker locker(m_manager_mutex);
4565a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    ListenerMatches predicate (listener);
4575a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4585a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4595a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    if (m_listeners.erase (&listener) == 0)
4605a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        return;
4615a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4625a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    while (1)
4635a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    {
4645a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        collection::iterator iter, end_iter = m_event_map.end();
4655a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        iter = find_if (m_event_map.begin(), end_iter, predicate);
4665a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        if (iter == end_iter)
4675a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham            break;
4685a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        else
4695a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham            m_event_map.erase(iter);
4705a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    }
4715a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
4725a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4735a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamvoid
4745a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::SignUpListenersForBroadcaster (Broadcaster &broadcaster)
4755a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
4765a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    Mutex::Locker locker(m_manager_mutex);
4775a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4785a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    collection::iterator iter = m_event_map.begin(), end_iter = m_event_map.end();
4795a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4805a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    while (iter != end_iter
4815a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham           && (iter = find_if (iter, end_iter, BroadcasterClassMatches(broadcaster.GetBroadcasterClass()))) != end_iter)
4825a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    {
4835a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        (*iter).second->StartListeningForEvents (&broadcaster, (*iter).first.GetEventBits());
4845a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        iter++;
4855a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    }
4865a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
4875a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4885a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamvoid
4895a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamBroadcasterManager::Clear ()
4905a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
4915a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    Mutex::Locker locker(m_manager_mutex);
4925a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    listener_collection::iterator end_iter = m_listeners.end();
4935a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4945a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    for (listener_collection::iterator iter = m_listeners.begin(); iter != end_iter; iter++)
4955a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        (*iter)->BroadcasterManagerWillDestruct(this);
4965a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    m_listeners.clear();
4975a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    m_event_map.clear();
4985a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
4995a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
500