diff options
author | Eugene Ostroukhov <eostroukhov@google.com> | 2018-09-09 05:45:10 +0300 |
---|---|---|
committer | Michaƫl Zasso <targos@protonmail.com> | 2018-09-25 09:53:37 +0300 |
commit | 1c3a2ebfcf0a5b3d7c7424619ea31ef0fdcca03a (patch) | |
tree | fefed653516357f3722d8041de6c44c9bf8e2eb7 /src | |
parent | 600c22543993d125e0973e7703ff7f4a478b1584 (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.cc | 7 | ||||
-rw-r--r-- | src/inspector/main_thread_interface.h | 1 | ||||
-rw-r--r-- | src/inspector/tracing_agent.cc | 13 | ||||
-rw-r--r-- | src/inspector_agent.cc | 30 | ||||
-rw-r--r-- | src/inspector_agent.h | 4 | ||||
-rw-r--r-- | src/node.cc | 2 | ||||
-rw-r--r-- | src/node_worker.cc | 32 | ||||
-rw-r--r-- | src/node_worker.h | 3 |
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_; |