1#ifndef SRC_INSPECTOR_WORKER_INSPECTOR_H_
2#define SRC_INSPECTOR_WORKER_INSPECTOR_H_
3
4#if !HAVE_INSPECTOR
5#error("This header can only be used when inspector is enabled")
6#endif
7
8#include <memory>
9#include <string>
10#include <unordered_map>
11#include <unordered_set>
12
13namespace node {
14namespace inspector {
15class InspectorSession;
16class InspectorSessionDelegate;
17class MainThreadHandle;
18class WorkerManager;
19
20class WorkerDelegate {
21 public:
22  virtual void WorkerCreated(const std::string& title,
23                             const std::string& url,
24                             bool waiting,
25                             std::shared_ptr<MainThreadHandle> worker) = 0;
26  virtual ~WorkerDelegate() = default;
27};
28
29class WorkerManagerEventHandle {
30 public:
31  explicit WorkerManagerEventHandle(std::shared_ptr<WorkerManager> manager,
32                                    int id)
33                                    : manager_(manager), id_(id) {}
34  void SetWaitOnStart(bool wait_on_start);
35  ~WorkerManagerEventHandle();
36
37 private:
38  std::shared_ptr<WorkerManager> manager_;
39  int id_;
40};
41
42struct WorkerInfo {
43  WorkerInfo(const std::string& target_title,
44             const std::string& target_url,
45             std::shared_ptr<MainThreadHandle> worker_thread)
46             : title(target_title),
47               url(target_url),
48               worker_thread(worker_thread) {}
49  std::string title;
50  std::string url;
51  std::shared_ptr<MainThreadHandle> worker_thread;
52};
53
54class ParentInspectorHandle {
55 public:
56  ParentInspectorHandle(uint64_t id,
57                        const std::string& url,
58                        std::shared_ptr<MainThreadHandle> parent_thread,
59                        bool wait_for_connect,
60                        const std::string& name);
61  ~ParentInspectorHandle();
62  std::unique_ptr<ParentInspectorHandle> NewParentInspectorHandle(
63      uint64_t thread_id, const std::string& url, const std::string& name) {
64    return std::make_unique<ParentInspectorHandle>(
65        thread_id, url, parent_thread_, wait_, name);
66  }
67  void WorkerStarted(std::shared_ptr<MainThreadHandle> worker_thread,
68                     bool waiting);
69  bool WaitForConnect() {
70    return wait_;
71  }
72  const std::string& url() const { return url_; }
73  std::unique_ptr<inspector::InspectorSession> Connect(
74      std::unique_ptr<inspector::InspectorSessionDelegate> delegate,
75      bool prevent_shutdown);
76
77 private:
78  uint64_t id_;
79  std::string url_;
80  std::shared_ptr<MainThreadHandle> parent_thread_;
81  bool wait_;
82  std::string name_;
83};
84
85class WorkerManager : public std::enable_shared_from_this<WorkerManager> {
86 public:
87  explicit WorkerManager(std::shared_ptr<MainThreadHandle> thread)
88                         : thread_(thread) {}
89
90  std::unique_ptr<ParentInspectorHandle> NewParentHandle(
91      uint64_t thread_id, const std::string& url, const std::string& name);
92  void WorkerStarted(uint64_t session_id, const WorkerInfo& info, bool waiting);
93  void WorkerFinished(uint64_t session_id);
94  std::unique_ptr<WorkerManagerEventHandle> SetAutoAttach(
95      std::unique_ptr<WorkerDelegate> attach_delegate);
96  void SetWaitOnStartForDelegate(int id, bool wait);
97  void RemoveAttachDelegate(int id);
98  std::shared_ptr<MainThreadHandle> MainThread() {
99    return thread_;
100  }
101
102 private:
103  std::shared_ptr<MainThreadHandle> thread_;
104  std::unordered_map<uint64_t, WorkerInfo> children_;
105  std::unordered_map<int, std::unique_ptr<WorkerDelegate>> delegates_;
106  // If any one needs it, workers stop for all
107  std::unordered_set<int> delegates_waiting_on_start_;
108  int next_delegate_id_ = 0;
109};
110}  // namespace inspector
111}  // namespace node
112
113#endif  // SRC_INSPECTOR_WORKER_INSPECTOR_H_
114