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 <stddef.h>
27#include <stdint.h>
28
29namespace lldb_private {
30class ConstString;
31class Event;
32}
33
34namespace lldb_private {
35
36class Listener : public std::enable_shared_from_this<Listener> {
37public:
38  typedef bool (*HandleBroadcastCallback)(lldb::EventSP &event_sp, void *baton);
39
40  friend class Broadcaster;
41  friend class BroadcasterManager;
42
43  // Constructors and Destructors
44  //
45  // Listeners have to be constructed into shared pointers - at least if you
46  // want them to listen to Broadcasters,
47protected:
48  Listener(const char *name);
49
50public:
51  static lldb::ListenerSP MakeListener(const char *name);
52
53  ~Listener();
54
55  void AddEvent(lldb::EventSP &event);
56
57  void Clear();
58
59  const char *GetName() { return m_name.c_str(); }
60
61  uint32_t
62  StartListeningForEventSpec(const lldb::BroadcasterManagerSP &manager_sp,
63                             const BroadcastEventSpec &event_spec);
64
65  bool StopListeningForEventSpec(const lldb::BroadcasterManagerSP &manager_sp,
66                                 const BroadcastEventSpec &event_spec);
67
68  uint32_t StartListeningForEvents(Broadcaster *broadcaster,
69                                   uint32_t event_mask);
70
71  uint32_t StartListeningForEvents(Broadcaster *broadcaster,
72                                   uint32_t event_mask,
73                                   HandleBroadcastCallback callback,
74                                   void *callback_user_data);
75
76  bool StopListeningForEvents(Broadcaster *broadcaster, uint32_t event_mask);
77
78  Event *PeekAtNextEvent();
79
80  Event *PeekAtNextEventForBroadcaster(Broadcaster *broadcaster);
81
82  Event *PeekAtNextEventForBroadcasterWithType(Broadcaster *broadcaster,
83                                               uint32_t event_type_mask);
84
85  // Returns true if an event was received, false if we timed out.
86  bool GetEvent(lldb::EventSP &event_sp, const Timeout<std::micro> &timeout);
87
88  bool GetEventForBroadcaster(Broadcaster *broadcaster, lldb::EventSP &event_sp,
89                              const Timeout<std::micro> &timeout);
90
91  bool GetEventForBroadcasterWithType(Broadcaster *broadcaster,
92                                      uint32_t event_type_mask,
93                                      lldb::EventSP &event_sp,
94                                      const Timeout<std::micro> &timeout);
95
96  size_t HandleBroadcastEvent(lldb::EventSP &event_sp);
97
98private:
99  // Classes that inherit from Listener can see and modify these
100  struct BroadcasterInfo {
101    BroadcasterInfo(uint32_t mask, HandleBroadcastCallback cb = nullptr,
102                    void *ud = nullptr)
103        : event_mask(mask), callback(cb), callback_user_data(ud) {}
104
105    uint32_t event_mask;
106    HandleBroadcastCallback callback;
107    void *callback_user_data;
108  };
109
110  typedef std::multimap<Broadcaster::BroadcasterImplWP, BroadcasterInfo,
111                        std::owner_less<Broadcaster::BroadcasterImplWP>>
112      broadcaster_collection;
113  typedef std::list<lldb::EventSP> event_collection;
114  typedef std::vector<lldb::BroadcasterManagerWP>
115      broadcaster_manager_collection;
116
117  bool
118  FindNextEventInternal(std::unique_lock<std::mutex> &lock,
119                        Broadcaster *broadcaster, // nullptr for any broadcaster
120                        const ConstString *sources, // nullptr for any event
121                        uint32_t num_sources, uint32_t event_type_mask,
122                        lldb::EventSP &event_sp, bool remove);
123
124  bool GetEventInternal(const Timeout<std::micro> &timeout,
125                        Broadcaster *broadcaster, // nullptr for any broadcaster
126                        const ConstString *sources, // nullptr for any event
127                        uint32_t num_sources, uint32_t event_type_mask,
128                        lldb::EventSP &event_sp);
129
130  std::string m_name;
131  broadcaster_collection m_broadcasters;
132  std::recursive_mutex m_broadcasters_mutex; // Protects m_broadcasters
133  event_collection m_events;
134  std::mutex m_events_mutex; // Protects m_broadcasters and m_events
135  std::condition_variable m_events_condition;
136  broadcaster_manager_collection m_broadcaster_managers;
137
138  void BroadcasterWillDestruct(Broadcaster *);
139
140  void BroadcasterManagerWillDestruct(lldb::BroadcasterManagerSP manager_sp);
141
142  //    broadcaster_collection::iterator
143  //    FindBroadcasterWithMask (Broadcaster *broadcaster,
144  //                             uint32_t event_mask,
145  //                             bool exact);
146
147  // For Listener only
148  DISALLOW_COPY_AND_ASSIGN(Listener);
149};
150
151} // namespace lldb_private
152
153#endif // LLDB_UTILITY_LISTENER_H
154