diff options
author | Anna Henningsen <anna@addaleax.net> | 2019-10-19 01:53:38 +0300 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2019-10-24 00:13:30 +0300 |
commit | 7a82e5ee62e5a3a29059581f208d960ff3ec8696 (patch) | |
tree | d2d545b046e7873fb4a4ec4959df2a97b26fa693 /src/inspector | |
parent | 5a042a6b1a9763be010c4614436b114f0d514561 (diff) |
inspector: turn platform tasks that outlive Agent into no-ops
Turn tasks scheduled on the `v8::Isolate` or on the given platform
into no-ops if the underlying `MainThreadInterface` has gone away
before the task could be run (which would happen when the
`Environment` instance and with it the `inspector::Agent` instance
are destroyed).
This addresses an issue that Electron has been having with
inspector support, and generally just seems like the right thing
to do, as we may not fully be in control of the relative timing
of Environment teardown, platform tasksexecution, and the
execution of `RequestInterrupt()` callbacks (although
the former two always happen in the same order in our own code).
PR-URL: https://github.com/nodejs/node/pull/30031
Reviewed-By: Eugene Ostroukhov <eostroukhov@google.com>
Reviewed-By: Shelley Vohr <codebytere@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'src/inspector')
-rw-r--r-- | src/inspector/main_thread_interface.cc | 21 | ||||
-rw-r--r-- | src/inspector/main_thread_interface.h | 3 |
2 files changed, 15 insertions, 9 deletions
diff --git a/src/inspector/main_thread_interface.cc b/src/inspector/main_thread_interface.cc index ac4461baed4..48a964d564f 100644 --- a/src/inspector/main_thread_interface.cc +++ b/src/inspector/main_thread_interface.cc @@ -87,15 +87,15 @@ class CallRequest : public Request { class DispatchMessagesTask : public v8::Task { public: - explicit DispatchMessagesTask(MainThreadInterface* thread) + explicit DispatchMessagesTask(std::weak_ptr<MainThreadInterface> thread) : thread_(thread) {} void Run() override { - thread_->DispatchMessages(); + if (auto thread = thread_.lock()) thread->DispatchMessages(); } private: - MainThreadInterface* thread_; + std::weak_ptr<MainThreadInterface> thread_; }; template <typename T> @@ -231,11 +231,16 @@ void MainThreadInterface::Post(std::unique_ptr<Request> request) { if (needs_notify) { if (isolate_ != nullptr && platform_ != nullptr) { std::shared_ptr<v8::TaskRunner> taskrunner = - platform_->GetForegroundTaskRunner(isolate_); - taskrunner->PostTask(std::make_unique<DispatchMessagesTask>(this)); - isolate_->RequestInterrupt([](v8::Isolate* isolate, void* thread) { - static_cast<MainThreadInterface*>(thread)->DispatchMessages(); - }, this); + platform_->GetForegroundTaskRunner(isolate_); + std::weak_ptr<MainThreadInterface>* interface_ptr = + new std::weak_ptr<MainThreadInterface>(shared_from_this()); + taskrunner->PostTask( + std::make_unique<DispatchMessagesTask>(*interface_ptr)); + isolate_->RequestInterrupt([](v8::Isolate* isolate, void* opaque) { + std::unique_ptr<std::weak_ptr<MainThreadInterface>> interface_ptr { + static_cast<std::weak_ptr<MainThreadInterface>*>(opaque) }; + if (auto iface = interface_ptr->lock()) iface->DispatchMessages(); + }, static_cast<void*>(interface_ptr)); } } incoming_message_cond_.Broadcast(scoped_lock); diff --git a/src/inspector/main_thread_interface.h b/src/inspector/main_thread_interface.h index 9a48192cd37..bcea19f3f39 100644 --- a/src/inspector/main_thread_interface.h +++ b/src/inspector/main_thread_interface.h @@ -70,7 +70,8 @@ class MainThreadHandle : public std::enable_shared_from_this<MainThreadHandle> { friend class MainThreadInterface; }; -class MainThreadInterface { +class MainThreadInterface : + public std::enable_shared_from_this<MainThreadInterface> { public: MainThreadInterface(Agent* agent, uv_loop_t*, v8::Isolate* isolate, v8::Platform* platform); |