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