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