diff --git a/src/env.h b/src/env.h index 98a3172075ce6e..f947f0bf4301fc 100644 --- a/src/env.h +++ b/src/env.h @@ -1273,6 +1273,9 @@ class Environment : public MemoryRetainer { inline void set_process_exit_handler( std::function&& handler); + void RunAndClearNativeImmediates(bool only_refed = false); + void RunAndClearInterrupts(); + private: inline void ThrowError(v8::Local (*fun)(v8::Local), const char* errmsg); @@ -1410,8 +1413,6 @@ class Environment : public MemoryRetainer { // yet or already have been destroyed. bool task_queues_async_initialized_ = false; - void RunAndClearNativeImmediates(bool only_refed = false); - void RunAndClearInterrupts(); std::atomic interrupt_data_ {nullptr}; void RequestInterruptFromV8(); static void CheckImmediate(uv_check_t* handle); diff --git a/src/inspector/main_thread_interface.cc b/src/inspector/main_thread_interface.cc index 48a964d564fec2..a15cd52d239e40 100644 --- a/src/inspector/main_thread_interface.cc +++ b/src/inspector/main_thread_interface.cc @@ -1,5 +1,6 @@ #include "main_thread_interface.h" +#include "env-inl.h" #include "node_mutex.h" #include "v8-inspector.h" #include "util-inl.h" @@ -85,19 +86,6 @@ class CallRequest : public Request { Fn fn_; }; -class DispatchMessagesTask : public v8::Task { - public: - explicit DispatchMessagesTask(std::weak_ptr thread) - : thread_(thread) {} - - void Run() override { - if (auto thread = thread_.lock()) thread->DispatchMessages(); - } - - private: - std::weak_ptr thread_; -}; - template class AnotherThreadObjectReference { public: @@ -212,12 +200,7 @@ class ThreadSafeDelegate : public InspectorSessionDelegate { } // namespace -MainThreadInterface::MainThreadInterface(Agent* agent, uv_loop_t* loop, - v8::Isolate* isolate, - v8::Platform* platform) - : agent_(agent), isolate_(isolate), - platform_(platform) { -} +MainThreadInterface::MainThreadInterface(Agent* agent) : agent_(agent) {} MainThreadInterface::~MainThreadInterface() { if (handle_) @@ -225,23 +208,15 @@ MainThreadInterface::~MainThreadInterface() { } void MainThreadInterface::Post(std::unique_ptr request) { + CHECK_NOT_NULL(agent_); Mutex::ScopedLock scoped_lock(requests_lock_); bool needs_notify = requests_.empty(); requests_.push_back(std::move(request)); if (needs_notify) { - if (isolate_ != nullptr && platform_ != nullptr) { - std::shared_ptr taskrunner = - platform_->GetForegroundTaskRunner(isolate_); - std::weak_ptr* interface_ptr = - new std::weak_ptr(shared_from_this()); - taskrunner->PostTask( - std::make_unique(*interface_ptr)); - isolate_->RequestInterrupt([](v8::Isolate* isolate, void* opaque) { - std::unique_ptr> interface_ptr { - static_cast*>(opaque) }; - if (auto iface = interface_ptr->lock()) iface->DispatchMessages(); - }, static_cast(interface_ptr)); - } + std::weak_ptr weak_self {shared_from_this()}; + agent_->env()->RequestInterrupt([weak_self](Environment*) { + if (auto iface = weak_self.lock()) iface->DispatchMessages(); + }); } incoming_message_cond_.Broadcast(scoped_lock); } @@ -274,7 +249,7 @@ void MainThreadInterface::DispatchMessages() { std::swap(dispatching_message_queue_.front(), task); dispatching_message_queue_.pop_front(); - v8::SealHandleScope seal_handle_scope(isolate_); + v8::SealHandleScope seal_handle_scope(agent_->env()->isolate()); task->Call(this); } } while (had_messages); diff --git a/src/inspector/main_thread_interface.h b/src/inspector/main_thread_interface.h index 78337a25e43808..3ec5b3db3e1600 100644 --- a/src/inspector/main_thread_interface.h +++ b/src/inspector/main_thread_interface.h @@ -72,8 +72,7 @@ class MainThreadHandle : public std::enable_shared_from_this { class MainThreadInterface : public std::enable_shared_from_this { public: - MainThreadInterface(Agent* agent, uv_loop_t*, v8::Isolate* isolate, - v8::Platform* platform); + explicit MainThreadInterface(Agent* agent); ~MainThreadInterface(); void DispatchMessages(); @@ -98,8 +97,6 @@ class MainThreadInterface : ConditionVariable incoming_message_cond_; // Used from any thread Agent* const agent_; - v8::Isolate* const isolate_; - v8::Platform* const platform_; std::shared_ptr handle_; std::unordered_map> managed_objects_; }; diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc index 7d665aa5d1381f..26101fe0e13b5e 100644 --- a/src/inspector_agent.cc +++ b/src/inspector_agent.cc @@ -660,8 +660,7 @@ class NodeInspectorClient : public V8InspectorClient { std::shared_ptr getThreadHandle() { if (!interface_) { interface_ = std::make_shared( - env_->inspector_agent(), env_->event_loop(), env_->isolate(), - env_->isolate_data()->platform()); + env_->inspector_agent()); } return interface_->GetHandle(); } @@ -697,10 +696,9 @@ class NodeInspectorClient : public V8InspectorClient { running_nested_loop_ = true; - MultiIsolatePlatform* platform = env_->isolate_data()->platform(); while (shouldRunMessageLoop()) { if (interface_) interface_->WaitForFrontendEvent(); - while (platform->FlushForegroundTasks(env_->isolate())) {} + env_->RunAndClearInterrupts(); } running_nested_loop_ = false; } diff --git a/src/inspector_agent.h b/src/inspector_agent.h index 089077370db049..efd090c49b4311 100644 --- a/src/inspector_agent.h +++ b/src/inspector_agent.h @@ -116,6 +116,8 @@ class Agent { // Interface for interacting with inspectors in worker threads std::shared_ptr GetWorkerManager(); + inline Environment* env() const { return parent_env_; } + private: void ToggleAsyncHook(v8::Isolate* isolate, const v8::Global& fn); diff --git a/src/inspector_js_api.cc b/src/inspector_js_api.cc index acc767cb8745bb..8616575e066121 100644 --- a/src/inspector_js_api.cc +++ b/src/inspector_js_api.cc @@ -83,7 +83,7 @@ class JSBindingsConnection : public AsyncWrap { private: Environment* env_; - JSBindingsConnection* connection_; + BaseObjectPtr connection_; }; JSBindingsConnection(Environment* env, diff --git a/test/parallel/test-inspector-connect-main-thread.js b/test/parallel/test-inspector-connect-main-thread.js index bb21a54e90f1d1..be34981cd0c5be 100644 --- a/test/parallel/test-inspector-connect-main-thread.js +++ b/test/parallel/test-inspector-connect-main-thread.js @@ -76,6 +76,12 @@ function doConsoleLog(arrayBuffer) { // and do not interrupt the main code. Interrupting the code flow // can lead to unexpected behaviors. async function ensureListenerDoesNotInterrupt(session) { + // Make sure that the following code is not affected by the fact that it may + // run inside an inspector message callback, during which other inspector + // message callbacks (such as the one triggered by doConsoleLog()) would + // not be processed. + await new Promise(setImmediate); + const currentTime = Date.now(); let consoleLogHappened = false; session.once('Runtime.consoleAPICalled',