124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Listener.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/Listener.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/Broadcaster.h"
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Log.h"
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/StreamString.h"
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Event.h"
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Host/TimeValue.h"
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private-log.h"
22a408326b499c3ffdfed2378738598c4ad0cf745fEli Friedman#include <algorithm>
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::Listener(const char *name) :
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_name (name),
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_broadcasters(),
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_broadcasters_mutex (Mutex::eMutexTypeRecursive),
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_events (),
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_events_mutex (Mutex::eMutexTypeRecursive),
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_cond_wait()
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
35952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (log)
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        log->Printf ("%p Listener::Listener('%s')", this, m_name.c_str());
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::~Listener()
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
42952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
435a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    Mutex::Locker locker (m_broadcasters_mutex);
445a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
455a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    size_t num_managers = m_broadcaster_managers.size();
465a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
473e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs    for (size_t i = 0; i < num_managers; i++)
485a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        m_broadcaster_managers[i]->RemoveListener(*this);
495a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (log)
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        log->Printf ("%p Listener::~Listener('%s')", this, m_name.c_str());
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Clear();
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::Clear()
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Mutex::Locker locker(m_broadcasters_mutex);
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    broadcaster_collection::iterator pos, end = m_broadcasters.end();
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (pos = m_broadcasters.begin(); pos != end; ++pos)
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        pos->first->RemoveListener (this, pos->second.event_mask);
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_broadcasters.clear();
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_cond_wait.SetValue (false, eBroadcastNever);
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_broadcasters.clear();
652f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton    Mutex::Locker event_locker(m_events_mutex);
662f57db09a49f2a05a620b8163bbe1e748a46ec73Greg Clayton    m_events.clear();
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask)
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (broadcaster)
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Scope for "locker"
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Tell the broadcaster to add this object as a listener
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            Mutex::Locker locker(m_broadcasters_mutex);
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask)));
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t acquired_mask = broadcaster->AddListener (this, event_mask);
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (event_mask != acquired_mask)
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
87952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (log)
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s",
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                         this,
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                         broadcaster,
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                         event_mask,
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                         acquired_mask,
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                         m_name.c_str());
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return acquired_mask;
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 0;
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask, HandleBroadcastCallback callback, void *callback_user_data)
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (broadcaster)
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Scope for "locker"
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Tell the broadcaster to add this object as a listener
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            Mutex::Locker locker(m_broadcasters_mutex);
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask, callback, callback_user_data)));
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t acquired_mask = broadcaster->AddListener (this, event_mask);
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
116952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (log)
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x, callback = %p, user_data = %p) acquired_mask = 0x%8.8x for %s",
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        this, broadcaster, event_mask, callback, callback_user_data, acquired_mask, m_name.c_str());
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return acquired_mask;
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 0;
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::StopListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask)
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (broadcaster)
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Scope for "locker"
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            Mutex::Locker locker(m_broadcasters_mutex);
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_broadcasters.erase (broadcaster);
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Remove the broadcaster from our set of broadcasters
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return broadcaster->RemoveListener (this, event_mask);
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Called when a Broadcaster is in its destuctor. We need to remove all
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// knowledge of this broadcaster and any events that it may have queued up
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::BroadcasterWillDestruct (Broadcaster *broadcaster)
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Scope for "broadcasters_locker"
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Mutex::Locker broadcasters_locker(m_broadcasters_mutex);
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_broadcasters.erase (broadcaster);
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Scope for "event_locker"
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Mutex::Locker event_locker(m_events_mutex);
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Remove all events for this broadcaster object.
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        event_collection::iterator pos = m_events.begin();
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while (pos != m_events.end())
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if ((*pos)->GetBroadcaster() == broadcaster)
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                pos = m_events.erase(pos);
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                ++pos;
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (m_events.empty())
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_cond_wait.SetValue (false, eBroadcastNever);
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
1745a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamListener::BroadcasterManagerWillDestruct (BroadcasterManager *manager)
1755a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
1765a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    // Just need to remove this broadcast manager from the list of managers:
1775a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    broadcaster_manager_collection::iterator iter, end_iter = m_broadcaster_managers.end();
1785a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    iter = find(m_broadcaster_managers.begin(), end_iter, manager);
1795a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    if (iter != end_iter)
1805a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        m_broadcaster_managers.erase (iter);
1815a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
1825a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
1835a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamvoid
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::AddEvent (EventSP &event_sp)
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
186952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (log)
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        log->Printf ("%p Listener('%s')::AddEvent (event_sp = {%p})", this, m_name.c_str(), event_sp.get());
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Scope for "locker"
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Mutex::Locker locker(m_events_mutex);
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_events.push_back (event_sp);
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_cond_wait.SetValue (true, eBroadcastAlways);
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass EventBroadcasterMatches
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EventBroadcasterMatches (Broadcaster *broadcaster) :
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_broadcaster (broadcaster)    {
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool operator() (const EventSP &event_sp) const
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (event_sp->BroadcasterIs(m_broadcaster))
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return true;
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprivate:
21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Broadcaster *m_broadcaster;
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass EventMatcher
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EventMatcher (Broadcaster *broadcaster, const ConstString *broadcaster_names, uint32_t num_broadcaster_names, uint32_t event_type_mask) :
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_broadcaster (broadcaster),
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_broadcaster_names (broadcaster_names),
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_num_broadcaster_names (num_broadcaster_names),
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_event_type_mask (event_type_mask)
22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool operator() (const EventSP &event_sp) const
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (m_broadcaster && !event_sp->BroadcasterIs(m_broadcaster))
23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (m_broadcaster_names)
23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            bool found_source = false;
23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            const ConstString &event_broadcaster_name = event_sp->GetBroadcaster()->GetBroadcasterName();
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            for (uint32_t i=0; i<m_num_broadcaster_names; ++i)
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (m_broadcaster_names[i] == event_broadcaster_name)
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    found_source = true;
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (!found_source)
24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return false;
24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (m_event_type_mask == 0 || m_event_type_mask & event_sp->GetType())
25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return true;
25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprivate:
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Broadcaster *m_broadcaster;
25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const ConstString *m_broadcaster_names;
25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t m_num_broadcaster_names;
25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t m_event_type_mask;
26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::FindNextEventInternal
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Broadcaster *broadcaster,   // NULL for any broadcaster
26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const ConstString *broadcaster_names, // NULL for any event
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t num_broadcaster_names,
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t event_type_mask,
27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EventSP &event_sp,
27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool remove)
27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
273952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Mutex::Locker lock(m_events_mutex);
27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_events.empty())
27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Listener::event_collection::iterator pos = m_events.end();
28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (broadcaster == NULL && broadcaster_names == NULL && event_type_mask == 0)
28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        pos = m_events.begin();
28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        pos = std::find_if (m_events.begin(), m_events.end(), EventMatcher (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask));
29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (pos != m_events.end())
29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        event_sp = *pos;
295e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton
296e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton        if (log)
297e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton            log->Printf ("%p '%s' Listener::FindNextEventInternal(broadcaster=%p, broadcaster_names=%p[%u], event_type_mask=0x%8.8x, remove=%i) event %p",
298e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton                         this,
299e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton                         GetName(),
300e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton                         broadcaster,
301e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton                         broadcaster_names,
302e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton                         num_broadcaster_names,
303e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton                         event_type_mask,
304e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton                         remove,
305e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton                         event_sp.get());
306e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton
30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (remove)
30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_events.erase(pos);
31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (m_events.empty())
31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                m_cond_wait.SetValue (false, eBroadcastNever);
31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3159e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham        // Unlock the event queue here.  We've removed this event and are about to return
3169e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham        // it so it should be okay to get the next event off the queue here - and it might
3179e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham        // be useful to do that in the "DoOnRemoval".
3189e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham        lock.Unlock();
3199e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham
320110accf5adf8d8b0710a13ef4d5fd778b0f9cdb7Jim Ingham        // Don't call DoOnRemoval if you aren't removing the event...
321110accf5adf8d8b0710a13ef4d5fd778b0f9cdb7Jim Ingham        if (remove)
322110accf5adf8d8b0710a13ef4d5fd778b0f9cdb7Jim Ingham            event_sp->DoOnRemoval();
323110accf5adf8d8b0710a13ef4d5fd778b0f9cdb7Jim Ingham
32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return true;
32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    event_sp.reset();
32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerEvent *
33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::PeekAtNextEvent ()
33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EventSP event_sp;
33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (FindNextEventInternal (NULL, NULL, 0, 0, event_sp, false))
33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return event_sp.get();
33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return NULL;
33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerEvent *
34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::PeekAtNextEventForBroadcaster (Broadcaster *broadcaster)
34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EventSP event_sp;
34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (FindNextEventInternal (broadcaster, NULL, 0, 0, event_sp, false))
34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return event_sp.get();
34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return NULL;
34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerEvent *
35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::PeekAtNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask)
35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EventSP event_sp;
35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (FindNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp, false))
35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return event_sp.get();
35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return NULL;
35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::GetNextEventInternal
36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Broadcaster *broadcaster,   // NULL for any broadcaster
36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const ConstString *broadcaster_names, // NULL for any event
36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t num_broadcaster_names,
36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t event_type_mask,
36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EventSP &event_sp
36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true);
37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::GetNextEvent (EventSP &event_sp)
37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return GetNextEventInternal (NULL, NULL, 0, 0, event_sp);
37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::GetNextEventForBroadcaster (Broadcaster *broadcaster, EventSP &event_sp)
38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return GetNextEventInternal (broadcaster, NULL, 0, 0, event_sp);
38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::GetNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask, EventSP &event_sp)
38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return GetNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp);
38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
39124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::WaitForEventsInternal
39424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
39524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const TimeValue *timeout,
39624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Broadcaster *broadcaster,   // NULL for any broadcaster
39724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const ConstString *broadcaster_names, // NULL for any event
39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t num_broadcaster_names,
39924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t event_type_mask,
40024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EventSP &event_sp
40124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
40224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
403952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
40424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool timed_out = false;
40524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
40624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (log)
40724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
40824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        log->Printf ("%p Listener::WaitForEventsInternal (timeout = { %p }) for %s",
40924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    this, timeout, m_name.c_str());
41024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
41124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
41224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    while (1)
41324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
4149e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham        // Note, we don't want to lock the m_events_mutex in the call to GetNextEventInternal, since the DoOnRemoval
4159e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham        // code might require that new events be serviced.  For instance, the Breakpoint Command's
4169e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham        if (GetNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp))
41715b3c94ed330d028269272ae9b1c84f2d9281abdGreg Clayton                return true;
41815b3c94ed330d028269272ae9b1c84f2d9281abdGreg Clayton
4199e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham        {
42015b3c94ed330d028269272ae9b1c84f2d9281abdGreg Clayton            // Reset condition value to false, so we can wait for new events to be
42115b3c94ed330d028269272ae9b1c84f2d9281abdGreg Clayton            // added that might meet our current filter
4229e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham            // But first poll for any new event that might satisfy our condition, and if so consume it,
4239e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham            // otherwise wait.
4249e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham
4259e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham            Mutex::Locker event_locker(m_events_mutex);
4269e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham            const bool remove = false;
4279e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham            if (FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, remove))
4289e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham                continue;
4299e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham            else
4309e3193a5c84b26a97fffc61de0b20dfbcfa54393Jim Ingham                m_cond_wait.SetValue (false, eBroadcastNever);
43115b3c94ed330d028269272ae9b1c84f2d9281abdGreg Clayton        }
43224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
43324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (m_cond_wait.WaitForValueEqualTo (true, timeout, &timed_out))
43424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            continue;
43524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
43624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else if (timed_out)
43724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
438926060e198137f8a64face70455324a8cd4362a5Caroline Tice            log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
43924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (log)
440e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton                log->Printf ("%p Listener::WaitForEventsInternal() timed out for %s", this, m_name.c_str());
44124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
44224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
44324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
44424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
445926060e198137f8a64face70455324a8cd4362a5Caroline Tice            log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
44624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (log)
447e6595ead6adb766b41699c7a7976c6e9eb2fdab8Greg Clayton                log->Printf ("%p Listener::WaitForEventsInternal() unknown error for %s", this, m_name.c_str());
44824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
44924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
45024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
45124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
45224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
45324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
45424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
45524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
45624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::WaitForEventForBroadcasterWithType
45724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
45824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const TimeValue *timeout,
45924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Broadcaster *broadcaster,
46024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t event_type_mask,
46124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EventSP &event_sp
46224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
46324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
46424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return WaitForEventsInternal (timeout, broadcaster, NULL, 0, event_type_mask, event_sp);
46524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
46624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
46724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
46824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::WaitForEventForBroadcaster
46924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
47024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const TimeValue *timeout,
47124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Broadcaster *broadcaster,
47224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    EventSP &event_sp
47324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
47424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return WaitForEventsInternal (timeout, broadcaster, NULL, 0, 0, event_sp);
47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
47724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
47824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
47924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::WaitForEvent (const TimeValue *timeout, EventSP &event_sp)
48024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
48124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return WaitForEventsInternal (timeout, NULL, NULL, 0, 0, event_sp);
48224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
48324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
48424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//Listener::broadcaster_collection::iterator
48524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//Listener::FindBroadcasterWithMask (Broadcaster *broadcaster, uint32_t event_mask, bool exact)
48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//{
48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//    broadcaster_collection::iterator pos;
48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//    broadcaster_collection::iterator end = m_broadcasters.end();
48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//    for (pos = m_broadcasters.find (broadcaster);
49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//        pos != end && pos->first == broadcaster;
49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//        ++pos)
49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//    {
49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//        if (exact)
49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//        {
49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//            if ((event_mask & pos->second.event_mask) == event_mask)
49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                return pos;
49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//        }
49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//        else
49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//        {
50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//            if (event_mask & pos->second.event_mask)
50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                return pos;
50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//        }
50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//    }
50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//    return end;
50524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//}
50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
50724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t
50824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener::HandleBroadcastEvent (EventSP &event_sp)
50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    size_t num_handled = 0;
51124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Mutex::Locker locker(m_broadcasters_mutex);
51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Broadcaster *broadcaster = event_sp->GetBroadcaster();
51324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    broadcaster_collection::iterator pos;
51424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    broadcaster_collection::iterator end = m_broadcasters.end();
51524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (pos = m_broadcasters.find (broadcaster);
51624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        pos != end && pos->first == broadcaster;
51724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ++pos)
51824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
51924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        BroadcasterInfo info = pos->second;
52024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (event_sp->GetType () & info.event_mask)
52124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
52224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (info.callback != NULL)
52324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
52424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                info.callback (event_sp, info.callback_user_data);
52524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                ++num_handled;
52624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
52824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
52924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return num_handled;
53024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5315a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
5325a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghamuint32_t
5335a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamListener::StartListeningForEventSpec (BroadcasterManager &manager,
5345a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham                             const BroadcastEventSpec &event_spec)
5355a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
536ac630b8ee6f36d0d2024d2dfd6525e1cdd727360Daniel Malea    // The BroadcasterManager mutex must be locked before m_broadcasters_mutex
537ac630b8ee6f36d0d2024d2dfd6525e1cdd727360Daniel Malea    // to avoid violating the lock hierarchy (manager before broadcasters).
538ac630b8ee6f36d0d2024d2dfd6525e1cdd727360Daniel Malea    Mutex::Locker manager_locker(manager.m_manager_mutex);
5395a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    Mutex::Locker locker(m_broadcasters_mutex);
5405a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
5415a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    uint32_t bits_acquired = manager.RegisterListenerForEvents(*this, event_spec);
5425a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    if (bits_acquired)
5435a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham        m_broadcaster_managers.push_back(&manager);
5445a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
5455a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    return bits_acquired;
5465a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
5475a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
5485a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Inghambool
5495a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamListener::StopListeningForEventSpec (BroadcasterManager &manager,
5505a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham                             const BroadcastEventSpec &event_spec)
5515a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{
5525a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    Mutex::Locker locker(m_broadcasters_mutex);
5535a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham    return manager.UnregisterListenerForEvents (*this, event_spec);
5545a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
5555a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham}
5565a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
5575a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham
558