Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEugene Ostroukhov <eostroukhov@google.com>2018-09-09 05:45:10 +0300
committerMichaƫl Zasso <targos@protonmail.com>2018-09-25 09:53:37 +0300
commit1c3a2ebfcf0a5b3d7c7424619ea31ef0fdcca03a (patch)
treefefed653516357f3722d8041de6c44c9bf8e2eb7 /src
parent600c22543993d125e0973e7703ff7f4a478b1584 (diff)
inspector: enable Inspector JS API in workers
PR-URL: https://github.com/nodejs/node/pull/22769 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/inspector/main_thread_interface.cc7
-rw-r--r--src/inspector/main_thread_interface.h1
-rw-r--r--src/inspector/tracing_agent.cc13
-rw-r--r--src/inspector_agent.cc30
-rw-r--r--src/inspector_agent.h4
-rw-r--r--src/node.cc2
-rw-r--r--src/node_worker.cc32
-rw-r--r--src/node_worker.h3
8 files changed, 68 insertions, 24 deletions
diff --git a/src/inspector/main_thread_interface.cc b/src/inspector/main_thread_interface.cc
index d8ee737ce2f..d3f553caac8 100644
--- a/src/inspector/main_thread_interface.cc
+++ b/src/inspector/main_thread_interface.cc
@@ -354,13 +354,6 @@ void MainThreadHandle::Reset() {
main_thread_ = nullptr;
}
-Agent* MainThreadHandle::GetInspectorAgent() {
- Mutex::ScopedLock scoped_lock(block_lock_);
- if (main_thread_ == nullptr)
- return nullptr;
- return main_thread_->inspector_agent();
-}
-
std::unique_ptr<InspectorSessionDelegate>
MainThreadHandle::MakeDelegateThreadSafe(
std::unique_ptr<InspectorSessionDelegate> delegate) {
diff --git a/src/inspector/main_thread_interface.h b/src/inspector/main_thread_interface.h
index db79db43821..7092310e553 100644
--- a/src/inspector/main_thread_interface.h
+++ b/src/inspector/main_thread_interface.h
@@ -54,7 +54,6 @@ class MainThreadHandle : public std::enable_shared_from_this<MainThreadHandle> {
return ++next_object_id_;
}
bool Post(std::unique_ptr<Request> request);
- Agent* GetInspectorAgent();
std::unique_ptr<InspectorSessionDelegate> MakeDelegateThreadSafe(
std::unique_ptr<InspectorSessionDelegate> delegate);
bool Expired();
diff --git a/src/inspector/tracing_agent.cc b/src/inspector/tracing_agent.cc
index 6e962b289ab..fe69e6f863e 100644
--- a/src/inspector/tracing_agent.cc
+++ b/src/inspector/tracing_agent.cc
@@ -74,11 +74,14 @@ DispatchResponse TracingAgent::start(
if (categories_set.empty())
return DispatchResponse::Error("At least one category should be enabled");
- trace_writer_ = env_->tracing_agent_writer()->agent()->AddClient(
- categories_set,
- std::unique_ptr<InspectorTraceWriter>(
- new InspectorTraceWriter(frontend_.get())),
- tracing::Agent::kIgnoreDefaultCategories);
+ auto* writer = env_->tracing_agent_writer();
+ if (writer != nullptr) {
+ trace_writer_ = env_->tracing_agent_writer()->agent()->AddClient(
+ categories_set,
+ std::unique_ptr<InspectorTraceWriter>(
+ new InspectorTraceWriter(frontend_.get())),
+ tracing::Agent::kIgnoreDefaultCategories);
+ }
return DispatchResponse::OK();
}
diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc
index da19eefe368..c8bface6bf5 100644
--- a/src/inspector_agent.cc
+++ b/src/inspector_agent.cc
@@ -189,6 +189,12 @@ static int StartDebugSignalHandler() {
const int CONTEXT_GROUP_ID = 1;
+std::string GetWorkerLabel(node::Environment* env) {
+ std::ostringstream result;
+ result << "Worker[" << env->thread_id() << "]";
+ return result.str();
+}
+
class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
public protocol::FrontendChannel {
public:
@@ -373,10 +379,13 @@ void NotifyClusterWorkersDebugEnabled(Environment* env) {
class NodeInspectorClient : public V8InspectorClient {
public:
- explicit NodeInspectorClient(node::Environment* env) : env_(env) {
+ explicit NodeInspectorClient(node::Environment* env, bool is_main)
+ : env_(env), is_main_(is_main) {
client_ = V8Inspector::create(env->isolate(), this);
// TODO(bnoordhuis) Make name configurable from src/node.cc.
- ContextInfo info(GetHumanReadableProcessName());
+ std::string name =
+ is_main_ ? GetHumanReadableProcessName() : GetWorkerLabel(env);
+ ContextInfo info(name);
info.is_default = true;
contextCreated(env->context(), info);
}
@@ -593,6 +602,7 @@ class NodeInspectorClient : public V8InspectorClient {
}
node::Environment* env_;
+ bool is_main_;
bool running_nested_loop_ = false;
std::unique_ptr<V8Inspector> client_;
std::unordered_map<int, std::unique_ptr<ChannelImpl>> channels_;
@@ -610,13 +620,23 @@ Agent::Agent(Environment* env)
: parent_env_(env),
debug_options_(env->options()->debug_options) {}
-Agent::~Agent() = default;
+Agent::~Agent() {
+ if (start_io_thread_async.data == this) {
+ start_io_thread_async.data = nullptr;
+ // This is global, will never get freed
+ uv_close(reinterpret_cast<uv_handle_t*>(&start_io_thread_async), nullptr);
+ }
+}
bool Agent::Start(const std::string& path,
- std::shared_ptr<DebugOptions> options) {
+ std::shared_ptr<DebugOptions> options,
+ bool is_main) {
+ if (options == nullptr) {
+ options = std::make_shared<DebugOptions>();
+ }
path_ = path;
debug_options_ = options;
- client_ = std::make_shared<NodeInspectorClient>(parent_env_);
+ client_ = std::make_shared<NodeInspectorClient>(parent_env_, is_main);
if (parent_env_->is_main_thread()) {
CHECK_EQ(0, uv_async_init(parent_env_->event_loop(),
&start_io_thread_async,
diff --git a/src/inspector_agent.h b/src/inspector_agent.h
index d9e2232dcc4..79ae8d4cd99 100644
--- a/src/inspector_agent.h
+++ b/src/inspector_agent.h
@@ -47,7 +47,9 @@ class Agent {
~Agent();
// Create client_, may create io_ if option enabled
- bool Start(const std::string& path, std::shared_ptr<DebugOptions> options);
+ bool Start(const std::string& path,
+ std::shared_ptr<DebugOptions> options,
+ bool is_worker);
// Stop and destroy io_
void Stop();
diff --git a/src/node.cc b/src/node.cc
index 678c1154b03..4b5a8d11325 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -327,7 +327,7 @@ static struct {
// right away on the websocket port and fails to bind/etc, this will return
// false.
return env->inspector_agent()->Start(
- script_path == nullptr ? "" : script_path, options);
+ script_path == nullptr ? "" : script_path, options, true);
}
bool InspectorStarted(Environment* env) {
diff --git a/src/node_worker.cc b/src/node_worker.cc
index 48364c84f6c..ba4ad9ccf70 100644
--- a/src/node_worker.cc
+++ b/src/node_worker.cc
@@ -35,10 +35,26 @@ namespace {
uint64_t next_thread_id = 1;
Mutex next_thread_id_mutex;
+#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR
+void StartWorkerInspector(Environment* child, const std::string& url) {
+ child->inspector_agent()->Start(url, nullptr, false);
+}
+
+void WaitForWorkerInspectorToStop(Environment* child) {
+ child->inspector_agent()->WaitForDisconnect();
+ child->inspector_agent()->Stop();
+}
+
+#else
+// No-ops
+void StartWorkerInspector(Environment* child, const std::string& url) {}
+void WaitForWorkerInspectorToStop(Environment* child) {}
+#endif
+
} // anonymous namespace
-Worker::Worker(Environment* env, Local<Object> wrap)
- : AsyncWrap(env, wrap, AsyncWrap::PROVIDER_WORKER) {
+Worker::Worker(Environment* env, Local<Object> wrap, const std::string& url)
+ : AsyncWrap(env, wrap, AsyncWrap::PROVIDER_WORKER), url_(url) {
// Generate a new thread id.
{
Mutex::ScopedLock next_thread_id_lock(next_thread_id_mutex);
@@ -155,6 +171,7 @@ void Worker::Run() {
env_->async_hooks()->pop_async_id(1);
Debug(this, "Loaded environment for worker %llu", thread_id_);
+ StartWorkerInspector(env_.get(), url_);
}
{
@@ -215,6 +232,7 @@ void Worker::Run() {
env_->stop_sub_worker_contexts();
env_->RunCleanup();
RunAtExit(env_.get());
+ WaitForWorkerInspectorToStop(env_.get());
{
Mutex::ScopedLock stopped_lock(stopped_mutex_);
@@ -350,7 +368,15 @@ void Worker::New(const FunctionCallbackInfo<Value>& args) {
return;
}
- new Worker(env, args.This());
+ std::string url;
+ // Argument might be a string or URL
+ if (args.Length() == 1 && !args[0]->IsNullOrUndefined()) {
+ Utf8Value value(
+ args.GetIsolate(),
+ args[0]->ToString(env->context()).FromMaybe(v8::Local<v8::String>()));
+ url.append(value.out(), value.length());
+ }
+ new Worker(env, args.This(), url);
}
void Worker::StartThread(const FunctionCallbackInfo<Value>& args) {
diff --git a/src/node_worker.h b/src/node_worker.h
index 33df36e04ce..8491ad221b6 100644
--- a/src/node_worker.h
+++ b/src/node_worker.h
@@ -12,7 +12,7 @@ namespace worker {
// A worker thread, as represented in its parent thread.
class Worker : public AsyncWrap {
public:
- Worker(Environment* env, v8::Local<v8::Object> wrap);
+ Worker(Environment* env, v8::Local<v8::Object> wrap, const std::string& url);
~Worker();
// Run the worker. This is only called from the worker thread.
@@ -52,6 +52,7 @@ class Worker : public AsyncWrap {
uv_loop_t loop_;
DeleteFnPtr<IsolateData, FreeIsolateData> isolate_data_;
DeleteFnPtr<Environment, FreeEnvironment> env_;
+ const std::string url_;
v8::Isolate* isolate_ = nullptr;
DeleteFnPtr<ArrayBufferAllocator, FreeArrayBufferAllocator>
array_buffer_allocator_;