1 #include "worker_inspector.h"
2 #include "main_thread_interface.h"
3 #include "util-inl.h"
4
5 #include <memory>
6
7 namespace node {
8 namespace inspector {
9 namespace {
10
11 class WorkerStartedRequest : public Request {
12 public:
WorkerStartedRequest(int id,const std::string & url,std::shared_ptr<node::inspector::MainThreadHandle> worker_thread,bool waiting)13 WorkerStartedRequest(
14 int id,
15 const std::string& url,
16 std::shared_ptr<node::inspector::MainThreadHandle> worker_thread,
17 bool waiting)
18 : id_(id),
19 info_(BuildWorkerTitle(id), url, worker_thread),
20 waiting_(waiting) {}
Call(MainThreadInterface * thread)21 void Call(MainThreadInterface* thread) override {
22 auto manager = thread->inspector_agent()->GetWorkerManager();
23 manager->WorkerStarted(id_, info_, waiting_);
24 }
25
26 private:
BuildWorkerTitle(int id)27 static std::string BuildWorkerTitle(int id) {
28 return "Worker " + std::to_string(id);
29 }
30
31 int id_;
32 WorkerInfo info_;
33 bool waiting_;
34 };
35
36
Report(const std::unique_ptr<WorkerDelegate> & delegate,const WorkerInfo & info,bool waiting)37 void Report(const std::unique_ptr<WorkerDelegate>& delegate,
38 const WorkerInfo& info, bool waiting) {
39 if (info.worker_thread)
40 delegate->WorkerCreated(info.title, info.url, waiting, info.worker_thread);
41 }
42
43 class WorkerFinishedRequest : public Request {
44 public:
WorkerFinishedRequest(int worker_id)45 explicit WorkerFinishedRequest(int worker_id) : worker_id_(worker_id) {}
46
Call(MainThreadInterface * thread)47 void Call(MainThreadInterface* thread) override {
48 thread->inspector_agent()->GetWorkerManager()->WorkerFinished(worker_id_);
49 }
50
51 private:
52 int worker_id_;
53 };
54 } // namespace
55
56
ParentInspectorHandle(int id,const std::string & url,std::shared_ptr<MainThreadHandle> parent_thread,bool wait_for_connect)57 ParentInspectorHandle::ParentInspectorHandle(
58 int id, const std::string& url,
59 std::shared_ptr<MainThreadHandle> parent_thread, bool wait_for_connect)
60 : id_(id), url_(url), parent_thread_(parent_thread),
61 wait_(wait_for_connect) {}
62
~ParentInspectorHandle()63 ParentInspectorHandle::~ParentInspectorHandle() {
64 parent_thread_->Post(
65 std::unique_ptr<Request>(new WorkerFinishedRequest(id_)));
66 }
67
WorkerStarted(std::shared_ptr<MainThreadHandle> worker_thread,bool waiting)68 void ParentInspectorHandle::WorkerStarted(
69 std::shared_ptr<MainThreadHandle> worker_thread, bool waiting) {
70 std::unique_ptr<Request> request(
71 new WorkerStartedRequest(id_, url_, worker_thread, waiting));
72 parent_thread_->Post(std::move(request));
73 }
74
Connect(std::unique_ptr<inspector::InspectorSessionDelegate> delegate,bool prevent_shutdown)75 std::unique_ptr<inspector::InspectorSession> ParentInspectorHandle::Connect(
76 std::unique_ptr<inspector::InspectorSessionDelegate> delegate,
77 bool prevent_shutdown) {
78 return parent_thread_->Connect(std::move(delegate), prevent_shutdown);
79 }
80
WorkerFinished(int session_id)81 void WorkerManager::WorkerFinished(int session_id) {
82 children_.erase(session_id);
83 }
84
WorkerStarted(int session_id,const WorkerInfo & info,bool waiting)85 void WorkerManager::WorkerStarted(int session_id,
86 const WorkerInfo& info,
87 bool waiting) {
88 if (info.worker_thread->Expired())
89 return;
90 children_.emplace(session_id, info);
91 for (const auto& delegate : delegates_) {
92 Report(delegate.second, info, waiting);
93 }
94 }
95
96 std::unique_ptr<ParentInspectorHandle>
NewParentHandle(int thread_id,const std::string & url)97 WorkerManager::NewParentHandle(int thread_id, const std::string& url) {
98 bool wait = !delegates_waiting_on_start_.empty();
99 return std::make_unique<ParentInspectorHandle>(thread_id, url, thread_, wait);
100 }
101
RemoveAttachDelegate(int id)102 void WorkerManager::RemoveAttachDelegate(int id) {
103 delegates_.erase(id);
104 delegates_waiting_on_start_.erase(id);
105 }
106
SetAutoAttach(std::unique_ptr<WorkerDelegate> attach_delegate)107 std::unique_ptr<WorkerManagerEventHandle> WorkerManager::SetAutoAttach(
108 std::unique_ptr<WorkerDelegate> attach_delegate) {
109 int id = ++next_delegate_id_;
110 delegates_[id] = std::move(attach_delegate);
111 const auto& delegate = delegates_[id];
112 for (const auto& worker : children_) {
113 // Waiting is only reported when a worker is started, same as browser
114 Report(delegate, worker.second, false);
115 }
116 return std::make_unique<WorkerManagerEventHandle>(shared_from_this(), id);
117 }
118
SetWaitOnStartForDelegate(int id,bool wait)119 void WorkerManager::SetWaitOnStartForDelegate(int id, bool wait) {
120 if (wait)
121 delegates_waiting_on_start_.insert(id);
122 else
123 delegates_waiting_on_start_.erase(id);
124 }
125
SetWaitOnStart(bool wait_on_start)126 void WorkerManagerEventHandle::SetWaitOnStart(bool wait_on_start) {
127 manager_->SetWaitOnStartForDelegate(id_, wait_on_start);
128 }
129
~WorkerManagerEventHandle()130 WorkerManagerEventHandle::~WorkerManagerEventHandle() {
131 manager_->RemoveAttachDelegate(id_);
132 }
133 } // namespace inspector
134 } // namespace node
135