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