1 //===-- Listener.h ----------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_UTILITY_LISTENER_H
10 #define LLDB_UTILITY_LISTENER_H
11 
12 #include "lldb/Utility/Broadcaster.h"
13 #include "lldb/Utility/Timeout.h"
14 #include "lldb/lldb-defines.h"
15 #include "lldb/lldb-forward.h"
16 
17 #include <condition_variable>
18 #include <list>
19 #include <map>
20 #include <memory>
21 #include <mutex>
22 #include <ratio>
23 #include <string>
24 #include <vector>
25 
26 #include <cstddef>
27 #include <cstdint>
28 
29 namespace lldb_private {
30 class Event;
31 }
32 
33 namespace lldb_private {
34 
35 class Listener : public std::enable_shared_from_this<Listener> {
36 public:
37   typedef bool (*HandleBroadcastCallback)(lldb::EventSP &event_sp, void *baton);
38 
39   friend class Broadcaster;
40   friend class BroadcasterManager;
41 
42   // Constructors and Destructors
43   //
44   // Listeners have to be constructed into shared pointers - at least if you
45   // want them to listen to Broadcasters,
46 protected:
47   Listener(const char *name);
48 
49 public:
50   static lldb::ListenerSP MakeListener(const char *name);
51 
52   ~Listener();
53 
54   void AddEvent(lldb::EventSP &event);
55 
56   void Clear();
57 
58   const char *GetName() { return m_name.c_str(); }
59 
60   uint32_t
61   StartListeningForEventSpec(const lldb::BroadcasterManagerSP &manager_sp,
62                              const BroadcastEventSpec &event_spec);
63 
64   bool StopListeningForEventSpec(const lldb::BroadcasterManagerSP &manager_sp,
65                                  const BroadcastEventSpec &event_spec);
66 
67   uint32_t StartListeningForEvents(Broadcaster *broadcaster,
68                                    uint32_t event_mask);
69 
70   uint32_t StartListeningForEvents(Broadcaster *broadcaster,
71                                    uint32_t event_mask,
72                                    HandleBroadcastCallback callback,
73                                    void *callback_user_data);
74 
75   bool StopListeningForEvents(Broadcaster *broadcaster, uint32_t event_mask);
76 
77   Event *PeekAtNextEvent();
78 
79   Event *PeekAtNextEventForBroadcaster(Broadcaster *broadcaster);
80 
81   Event *PeekAtNextEventForBroadcasterWithType(Broadcaster *broadcaster,
82                                                uint32_t event_type_mask);
83 
84   // Returns true if an event was received, false if we timed out.
85   bool GetEvent(lldb::EventSP &event_sp, const Timeout<std::micro> &timeout);
86 
87   bool GetEventForBroadcaster(Broadcaster *broadcaster, lldb::EventSP &event_sp,
88                               const Timeout<std::micro> &timeout);
89 
90   bool GetEventForBroadcasterWithType(Broadcaster *broadcaster,
91                                       uint32_t event_type_mask,
92                                       lldb::EventSP &event_sp,
93                                       const Timeout<std::micro> &timeout);
94 
95   size_t HandleBroadcastEvent(lldb::EventSP &event_sp);
96 
97   void SetShadow(bool is_shadow) { m_is_shadow = is_shadow; }
98 
99 private:
100   // Classes that inherit from Listener can see and modify these
101   struct BroadcasterInfo {
102     BroadcasterInfo(uint32_t mask, HandleBroadcastCallback cb = nullptr,
103                     void *ud = nullptr)
104         : event_mask(mask), callback(cb), callback_user_data(ud) {}
105 
106     uint32_t event_mask;
107     HandleBroadcastCallback callback;
108     void *callback_user_data;
109   };
110 
111   typedef std::multimap<Broadcaster::BroadcasterImplWP, BroadcasterInfo,
112                         std::owner_less<Broadcaster::BroadcasterImplWP>>
113       broadcaster_collection;
114   typedef std::list<lldb::EventSP> event_collection;
115   typedef std::vector<lldb::BroadcasterManagerWP>
116       broadcaster_manager_collection;
117 
118   bool
119   FindNextEventInternal(std::unique_lock<std::mutex> &lock,
120                         Broadcaster *broadcaster, // nullptr for any broadcaster
121                         uint32_t event_type_mask, lldb::EventSP &event_sp,
122                         bool remove);
123 
124   bool GetEventInternal(const Timeout<std::micro> &timeout,
125                         Broadcaster *broadcaster, // nullptr for any broadcaster
126                         uint32_t event_type_mask, lldb::EventSP &event_sp);
127 
128   std::string m_name;
129   broadcaster_collection m_broadcasters;
130   std::recursive_mutex m_broadcasters_mutex; // Protects m_broadcasters
131   event_collection m_events;
132   std::mutex m_events_mutex; // Protects m_broadcasters and m_events
133   std::condition_variable m_events_condition;
134   broadcaster_manager_collection m_broadcaster_managers;
135   bool m_is_shadow = false;
136 
137   void BroadcasterWillDestruct(Broadcaster *);
138 
139   void BroadcasterManagerWillDestruct(lldb::BroadcasterManagerSP manager_sp);
140 
141   //    broadcaster_collection::iterator
142   //    FindBroadcasterWithMask (Broadcaster *broadcaster,
143   //                             uint32_t event_mask,
144   //                             bool exact);
145 
146   // For Listener only
147   Listener(const Listener &) = delete;
148   const Listener &operator=(const Listener &) = delete;
149 };
150 
151 } // namespace lldb_private
152 
153 #endif // LLDB_UTILITY_LISTENER_H
154