//===-- Listener.h ----------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLDB_UTILITY_LISTENER_H #define LLDB_UTILITY_LISTENER_H #include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/Timeout.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-forward.h" #include #include #include #include #include #include #include #include #include #include namespace lldb_private { class ConstString; class Event; } namespace lldb_private { class Listener : public std::enable_shared_from_this { 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(const lldb::BroadcasterManagerSP &manager_sp, const BroadcastEventSpec &event_spec); bool StopListeningForEventSpec(const 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 &timeout); bool GetEventForBroadcaster(Broadcaster *broadcaster, lldb::EventSP &event_sp, const Timeout &timeout); bool GetEventForBroadcasterWithType(Broadcaster *broadcaster, uint32_t event_type_mask, lldb::EventSP &event_sp, const Timeout &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_collection; typedef std::list event_collection; typedef std::vector broadcaster_manager_collection; bool FindNextEventInternal(std::unique_lock &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 &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 // LLDB_UTILITY_LISTENER_H