• 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(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