1343181Sdim//===-- Listener.h ----------------------------------------------*- C++ -*-===// 2343181Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6343181Sdim// 7343181Sdim//===----------------------------------------------------------------------===// 8343181Sdim 9343181Sdim#ifndef LLDB_UTILITY_LISTENER_H 10343181Sdim#define LLDB_UTILITY_LISTENER_H 11343181Sdim 12343181Sdim#include "lldb/Utility/Broadcaster.h" 13343181Sdim#include "lldb/Utility/Timeout.h" 14343181Sdim#include "lldb/lldb-defines.h" 15343181Sdim#include "lldb/lldb-forward.h" 16343181Sdim 17343181Sdim#include <condition_variable> 18343181Sdim#include <list> 19343181Sdim#include <map> 20343181Sdim#include <memory> 21343181Sdim#include <mutex> 22343181Sdim#include <ratio> 23343181Sdim#include <string> 24343181Sdim#include <vector> 25343181Sdim 26343181Sdim#include <stddef.h> 27343181Sdim#include <stdint.h> 28343181Sdim 29343181Sdimnamespace lldb_private { 30343181Sdimclass ConstString; 31343181Sdimclass Event; 32343181Sdim} 33343181Sdim 34343181Sdimnamespace lldb_private { 35343181Sdim 36343181Sdimclass Listener : public std::enable_shared_from_this<Listener> { 37343181Sdimpublic: 38343181Sdim typedef bool (*HandleBroadcastCallback)(lldb::EventSP &event_sp, void *baton); 39343181Sdim 40343181Sdim friend class Broadcaster; 41343181Sdim friend class BroadcasterManager; 42343181Sdim 43343181Sdim // Constructors and Destructors 44343181Sdim // 45343181Sdim // Listeners have to be constructed into shared pointers - at least if you 46343181Sdim // want them to listen to Broadcasters, 47343181Sdimprotected: 48343181Sdim Listener(const char *name); 49343181Sdim 50343181Sdimpublic: 51343181Sdim static lldb::ListenerSP MakeListener(const char *name); 52343181Sdim 53343181Sdim ~Listener(); 54343181Sdim 55343181Sdim void AddEvent(lldb::EventSP &event); 56343181Sdim 57343181Sdim void Clear(); 58343181Sdim 59343181Sdim const char *GetName() { return m_name.c_str(); } 60343181Sdim 61353358Sdim uint32_t 62353358Sdim StartListeningForEventSpec(const lldb::BroadcasterManagerSP &manager_sp, 63353358Sdim const BroadcastEventSpec &event_spec); 64343181Sdim 65353358Sdim bool StopListeningForEventSpec(const lldb::BroadcasterManagerSP &manager_sp, 66343181Sdim const BroadcastEventSpec &event_spec); 67343181Sdim 68343181Sdim uint32_t StartListeningForEvents(Broadcaster *broadcaster, 69343181Sdim uint32_t event_mask); 70343181Sdim 71343181Sdim uint32_t StartListeningForEvents(Broadcaster *broadcaster, 72343181Sdim uint32_t event_mask, 73343181Sdim HandleBroadcastCallback callback, 74343181Sdim void *callback_user_data); 75343181Sdim 76343181Sdim bool StopListeningForEvents(Broadcaster *broadcaster, uint32_t event_mask); 77343181Sdim 78343181Sdim Event *PeekAtNextEvent(); 79343181Sdim 80343181Sdim Event *PeekAtNextEventForBroadcaster(Broadcaster *broadcaster); 81343181Sdim 82343181Sdim Event *PeekAtNextEventForBroadcasterWithType(Broadcaster *broadcaster, 83343181Sdim uint32_t event_type_mask); 84343181Sdim 85343181Sdim // Returns true if an event was received, false if we timed out. 86343181Sdim bool GetEvent(lldb::EventSP &event_sp, const Timeout<std::micro> &timeout); 87343181Sdim 88343181Sdim bool GetEventForBroadcaster(Broadcaster *broadcaster, lldb::EventSP &event_sp, 89343181Sdim const Timeout<std::micro> &timeout); 90343181Sdim 91343181Sdim bool GetEventForBroadcasterWithType(Broadcaster *broadcaster, 92343181Sdim uint32_t event_type_mask, 93343181Sdim lldb::EventSP &event_sp, 94343181Sdim const Timeout<std::micro> &timeout); 95343181Sdim 96343181Sdim size_t HandleBroadcastEvent(lldb::EventSP &event_sp); 97343181Sdim 98343181Sdimprivate: 99343181Sdim // Classes that inherit from Listener can see and modify these 100343181Sdim struct BroadcasterInfo { 101343181Sdim BroadcasterInfo(uint32_t mask, HandleBroadcastCallback cb = nullptr, 102343181Sdim void *ud = nullptr) 103343181Sdim : event_mask(mask), callback(cb), callback_user_data(ud) {} 104343181Sdim 105343181Sdim uint32_t event_mask; 106343181Sdim HandleBroadcastCallback callback; 107343181Sdim void *callback_user_data; 108343181Sdim }; 109343181Sdim 110343181Sdim typedef std::multimap<Broadcaster::BroadcasterImplWP, BroadcasterInfo, 111343181Sdim std::owner_less<Broadcaster::BroadcasterImplWP>> 112343181Sdim broadcaster_collection; 113343181Sdim typedef std::list<lldb::EventSP> event_collection; 114343181Sdim typedef std::vector<lldb::BroadcasterManagerWP> 115343181Sdim broadcaster_manager_collection; 116343181Sdim 117343181Sdim bool 118343181Sdim FindNextEventInternal(std::unique_lock<std::mutex> &lock, 119343181Sdim Broadcaster *broadcaster, // nullptr for any broadcaster 120343181Sdim const ConstString *sources, // nullptr for any event 121343181Sdim uint32_t num_sources, uint32_t event_type_mask, 122343181Sdim lldb::EventSP &event_sp, bool remove); 123343181Sdim 124343181Sdim bool GetEventInternal(const Timeout<std::micro> &timeout, 125343181Sdim Broadcaster *broadcaster, // nullptr for any broadcaster 126343181Sdim const ConstString *sources, // nullptr for any event 127343181Sdim uint32_t num_sources, uint32_t event_type_mask, 128343181Sdim lldb::EventSP &event_sp); 129343181Sdim 130343181Sdim std::string m_name; 131343181Sdim broadcaster_collection m_broadcasters; 132343181Sdim std::recursive_mutex m_broadcasters_mutex; // Protects m_broadcasters 133343181Sdim event_collection m_events; 134343181Sdim std::mutex m_events_mutex; // Protects m_broadcasters and m_events 135343181Sdim std::condition_variable m_events_condition; 136343181Sdim broadcaster_manager_collection m_broadcaster_managers; 137343181Sdim 138343181Sdim void BroadcasterWillDestruct(Broadcaster *); 139343181Sdim 140343181Sdim void BroadcasterManagerWillDestruct(lldb::BroadcasterManagerSP manager_sp); 141343181Sdim 142343181Sdim // broadcaster_collection::iterator 143343181Sdim // FindBroadcasterWithMask (Broadcaster *broadcaster, 144343181Sdim // uint32_t event_mask, 145343181Sdim // bool exact); 146343181Sdim 147343181Sdim // For Listener only 148343181Sdim DISALLOW_COPY_AND_ASSIGN(Listener); 149343181Sdim}; 150343181Sdim 151343181Sdim} // namespace lldb_private 152343181Sdim 153343181Sdim#endif // LLDB_UTILITY_LISTENER_H 154