From afca57981d7772a56dcbd548ce983927d0b67b86 Mon Sep 17 00:00:00 2001 From: Ali Ijaz Sheikh Date: Tue, 18 Sep 2018 14:04:45 -0700 Subject: [PATCH] trace_events: destroy platform before tracing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For safer shutdown, we should destroy the platform – and background threads - before the tracing infrastructure is destroyed. This change fixes the relative order of NodePlatform disposition and the tracing agent shutting down. This matches the nesting order for startup. Make the tracing agent own the tracing controller instead of platform to match the above. Fixes: https://github.com/nodejs/node/issues/22865 PR-URL: https://github.com/nodejs/node/pull/22938 Reviewed-By: Eugene Ostroukhov Reviewed-By: James M Snell Reviewed-By: Matteo Collina --- src/node.cc | 5 ++++- src/node_platform.cc | 7 +++---- src/node_platform.h | 3 ++- src/tracing/agent.cc | 11 +++++------ src/tracing/agent.h | 6 ++++-- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/node.cc b/src/node.cc index 592db84dcc88c7..7e8738080b3c5e 100644 --- a/src/node.cc +++ b/src/node.cc @@ -279,15 +279,18 @@ static struct { controller->AddTraceStateObserver(new NodeTraceStateObserver(controller)); tracing::TraceEventHelper::SetTracingController(controller); StartTracingAgent(); + // Tracing must be initialized before platform threads are created. platform_ = new NodePlatform(thread_pool_size, controller); V8::InitializePlatform(platform_); } void Dispose() { - tracing_agent_.reset(nullptr); platform_->Shutdown(); delete platform_; platform_ = nullptr; + // Destroy tracing after the platform (and platform threads) have been + // stopped. + tracing_agent_.reset(nullptr); } void DrainVMTasks(Isolate* isolate) { diff --git a/src/node_platform.cc b/src/node_platform.cc index 03ef07eb1c65a6..ad0cd0db3ec684 100644 --- a/src/node_platform.cc +++ b/src/node_platform.cc @@ -280,10 +280,9 @@ int PerIsolatePlatformData::unref() { NodePlatform::NodePlatform(int thread_pool_size, TracingController* tracing_controller) { if (tracing_controller) { - tracing_controller_.reset(tracing_controller); + tracing_controller_ = tracing_controller; } else { - TracingController* controller = new TracingController(); - tracing_controller_.reset(controller); + tracing_controller_ = new TracingController(); } background_task_runner_ = std::make_shared(thread_pool_size); @@ -457,7 +456,7 @@ double NodePlatform::CurrentClockTimeMillis() { } TracingController* NodePlatform::GetTracingController() { - return tracing_controller_.get(); + return tracing_controller_; } template diff --git a/src/node_platform.h b/src/node_platform.h index 8359119c2f0c7b..c89c6a5ff6708e 100644 --- a/src/node_platform.h +++ b/src/node_platform.h @@ -161,7 +161,8 @@ class NodePlatform : public MultiIsolatePlatform { std::unordered_map> per_isolate_; - std::unique_ptr tracing_controller_; + + v8::TracingController* tracing_controller_; std::shared_ptr background_task_runner_; }; diff --git a/src/tracing/agent.cc b/src/tracing/agent.cc index 5a4d637bda0356..fd5cb3387b14ae 100644 --- a/src/tracing/agent.cc +++ b/src/tracing/agent.cc @@ -48,8 +48,7 @@ using v8::platform::tracing::TraceConfig; using v8::platform::tracing::TraceWriter; using std::string; -Agent::Agent() { - tracing_controller_ = new TracingController(); +Agent::Agent() : tracing_controller_(new TracingController()) { tracing_controller_->Initialize(nullptr); CHECK_EQ(uv_loop_init(&tracing_loop_), 0); @@ -117,7 +116,7 @@ AgentWriterHandle Agent::AddClient( use_categories = &categories_with_default; } - ScopedSuspendTracing suspend(tracing_controller_, this); + ScopedSuspendTracing suspend(tracing_controller_.get(), this); int id = next_writer_id_++; AsyncTraceWriter* raw = writer.get(); writers_[id] = std::move(writer); @@ -157,7 +156,7 @@ void Agent::Disconnect(int client) { Mutex::ScopedLock lock(initialize_writer_mutex_); to_be_initialized_.erase(writers_[client].get()); } - ScopedSuspendTracing suspend(tracing_controller_, this); + ScopedSuspendTracing suspend(tracing_controller_.get(), this); writers_.erase(client); categories_.erase(client); } @@ -166,13 +165,13 @@ void Agent::Enable(int id, const std::set& categories) { if (categories.empty()) return; - ScopedSuspendTracing suspend(tracing_controller_, this, + ScopedSuspendTracing suspend(tracing_controller_.get(), this, id != kDefaultHandleId); categories_[id].insert(categories.begin(), categories.end()); } void Agent::Disable(int id, const std::set& categories) { - ScopedSuspendTracing suspend(tracing_controller_, this, + ScopedSuspendTracing suspend(tracing_controller_.get(), this, id != kDefaultHandleId); std::multiset& writer_categories = categories_[id]; for (const std::string& category : categories) { diff --git a/src/tracing/agent.h b/src/tracing/agent.h index 045aaef85e8ea6..bb2e514aee2914 100644 --- a/src/tracing/agent.h +++ b/src/tracing/agent.h @@ -68,7 +68,9 @@ class Agent { Agent(); ~Agent(); - TracingController* GetTracingController() { return tracing_controller_; } + TracingController* GetTracingController() { + return tracing_controller_.get(); + } enum UseDefaultCategoryMode { kUseDefaultCategories, @@ -119,7 +121,7 @@ class Agent { // These maps store the original arguments to AddClient(), by id. std::unordered_map> categories_; std::unordered_map> writers_; - TracingController* tracing_controller_ = nullptr; + std::unique_ptr tracing_controller_; // Variables related to initializing per-event-loop properties of individual // writers, such as libuv handles.