blob: 3d12f8fb33916d59f813c0ba305ff64caf1e6e9a [file] [log] [blame]
//===-- Listener.h ----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_Select_h_
#define liblldb_Select_h_
#include "lldb/Core/Broadcaster.h" // for Broadcaster::BroadcasterImplWP
#include "lldb/Utility/Timeout.h"
#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN
#include "lldb/lldb-forward.h" // for BroadcasterManagerWP, EventSP
#include <condition_variable>
#include <list>
#include <map>
#include <memory> // for owner_less, enable_shared_from_this
#include <mutex>
#include <ratio> // for micro
#include <string>
#include <vector>
#include <stddef.h> // for size_t
#include <stdint.h> // for uint32_t
namespace lldb_private {
class ConstString;
}
namespace lldb_private {
class Event;
}
namespace lldb_private {
class Listener : public std::enable_shared_from_this<Listener> {
public:
typedef bool (*HandleBroadcastCallback)(lldb::EventSP &event_sp, void *baton);
friend class Broadcaster;
friend class BroadcasterManager;
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
//
// Listeners have to be constructed into shared pointers - at least if you
// want them to listen to Broadcasters,
protected:
Listener(const char *name);
public:
static lldb::ListenerSP MakeListener(const char *name);
~Listener();
void AddEvent(lldb::EventSP &event);
void Clear();
const char *GetName() { return m_name.c_str(); }
uint32_t StartListeningForEventSpec(lldb::BroadcasterManagerSP manager_sp,
const BroadcastEventSpec &event_spec);
bool StopListeningForEventSpec(lldb::BroadcasterManagerSP manager_sp,
const BroadcastEventSpec &event_spec);
uint32_t StartListeningForEvents(Broadcaster *broadcaster,
uint32_t event_mask);
uint32_t StartListeningForEvents(Broadcaster *broadcaster,
uint32_t event_mask,
HandleBroadcastCallback callback,
void *callback_user_data);
bool StopListeningForEvents(Broadcaster *broadcaster, uint32_t event_mask);
Event *PeekAtNextEvent();
Event *PeekAtNextEventForBroadcaster(Broadcaster *broadcaster);
Event *PeekAtNextEventForBroadcasterWithType(Broadcaster *broadcaster,
uint32_t event_type_mask);
// Returns true if an event was received, false if we timed out.
bool GetEvent(lldb::EventSP &event_sp, const Timeout<std::micro> &timeout);
bool GetEventForBroadcaster(Broadcaster *broadcaster, lldb::EventSP &event_sp,
const Timeout<std::micro> &timeout);
bool GetEventForBroadcasterWithType(Broadcaster *broadcaster,
uint32_t event_type_mask,
lldb::EventSP &event_sp,
const Timeout<std::micro> &timeout);
size_t HandleBroadcastEvent(lldb::EventSP &event_sp);
private:
//------------------------------------------------------------------
// Classes that inherit from Listener can see and modify these
//------------------------------------------------------------------
struct BroadcasterInfo {
BroadcasterInfo(uint32_t mask, HandleBroadcastCallback cb = nullptr,
void *ud = nullptr)
: event_mask(mask), callback(cb), callback_user_data(ud) {}
uint32_t event_mask;
HandleBroadcastCallback callback;
void *callback_user_data;
};
typedef std::multimap<Broadcaster::BroadcasterImplWP, BroadcasterInfo,
std::owner_less<Broadcaster::BroadcasterImplWP>>
broadcaster_collection;
typedef std::list<lldb::EventSP> event_collection;
typedef std::vector<lldb::BroadcasterManagerWP>
broadcaster_manager_collection;
bool
FindNextEventInternal(std::unique_lock<std::mutex> &lock,
Broadcaster *broadcaster, // nullptr for any broadcaster
const ConstString *sources, // nullptr for any event
uint32_t num_sources, uint32_t event_type_mask,
lldb::EventSP &event_sp, bool remove);
bool GetEventInternal(const Timeout<std::micro> &timeout,
Broadcaster *broadcaster, // nullptr for any broadcaster
const ConstString *sources, // nullptr for any event
uint32_t num_sources, uint32_t event_type_mask,
lldb::EventSP &event_sp);
std::string m_name;
broadcaster_collection m_broadcasters;
std::recursive_mutex m_broadcasters_mutex; // Protects m_broadcasters
event_collection m_events;
std::mutex m_events_mutex; // Protects m_broadcasters and m_events
std::condition_variable m_events_condition;
broadcaster_manager_collection m_broadcaster_managers;
void BroadcasterWillDestruct(Broadcaster *);
void BroadcasterManagerWillDestruct(lldb::BroadcasterManagerSP manager_sp);
// broadcaster_collection::iterator
// FindBroadcasterWithMask (Broadcaster *broadcaster,
// uint32_t event_mask,
// bool exact);
//------------------------------------------------------------------
// For Listener only
//------------------------------------------------------------------
DISALLOW_COPY_AND_ASSIGN(Listener);
};
} // namespace lldb_private
#endif // liblldb_Select_h_