inspector: libuv notification on incoming message
Currently Inspector posts a V8 "task" when a message is incoming. To make sure messages are processed even when no JS is executed (e.g. while waiting for I/O or timer), inspector will now post a libuv request. Fixes: https://github.com/nodejs/node/issues/11589 PR-URL: https://github.com/nodejs/node/pull/11617 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
parent
4cb9f4fde4
commit
f01fd2ae70
@ -159,6 +159,7 @@ class AgentImpl {
|
|||||||
|
|
||||||
static void ThreadCbIO(void* agent);
|
static void ThreadCbIO(void* agent);
|
||||||
static void WriteCbIO(uv_async_t* async);
|
static void WriteCbIO(uv_async_t* async);
|
||||||
|
static void MainThreadAsyncCb(uv_async_t* req);
|
||||||
|
|
||||||
void InstallInspectorOnProcess();
|
void InstallInspectorOnProcess();
|
||||||
|
|
||||||
@ -190,6 +191,7 @@ class AgentImpl {
|
|||||||
node::Environment* parent_env_;
|
node::Environment* parent_env_;
|
||||||
|
|
||||||
uv_async_t io_thread_req_;
|
uv_async_t io_thread_req_;
|
||||||
|
uv_async_t main_thread_req_;
|
||||||
V8NodeInspector* inspector_;
|
V8NodeInspector* inspector_;
|
||||||
v8::Platform* platform_;
|
v8::Platform* platform_;
|
||||||
MessageQueue<InspectorAction> incoming_message_queue_;
|
MessageQueue<InspectorAction> incoming_message_queue_;
|
||||||
@ -334,6 +336,9 @@ AgentImpl::AgentImpl(Environment* env) : delegate_(nullptr),
|
|||||||
dispatching_messages_(false),
|
dispatching_messages_(false),
|
||||||
session_id_(0),
|
session_id_(0),
|
||||||
server_(nullptr) {
|
server_(nullptr) {
|
||||||
|
CHECK_EQ(0, uv_async_init(env->event_loop(), &main_thread_req_,
|
||||||
|
AgentImpl::MainThreadAsyncCb));
|
||||||
|
uv_unref(reinterpret_cast<uv_handle_t*>(&main_thread_req_));
|
||||||
CHECK_EQ(0, uv_sem_init(&start_sem_, 0));
|
CHECK_EQ(0, uv_sem_init(&start_sem_, 0));
|
||||||
memset(&io_thread_req_, 0, sizeof(io_thread_req_));
|
memset(&io_thread_req_, 0, sizeof(io_thread_req_));
|
||||||
}
|
}
|
||||||
@ -416,10 +421,7 @@ bool AgentImpl::Start(v8::Platform* platform, const char* path,
|
|||||||
|
|
||||||
InstallInspectorOnProcess();
|
InstallInspectorOnProcess();
|
||||||
|
|
||||||
int err = uv_loop_init(&child_loop_);
|
int err = uv_thread_create(&thread_, AgentImpl::ThreadCbIO, this);
|
||||||
CHECK_EQ(err, 0);
|
|
||||||
|
|
||||||
err = uv_thread_create(&thread_, AgentImpl::ThreadCbIO, this);
|
|
||||||
CHECK_EQ(err, 0);
|
CHECK_EQ(err, 0);
|
||||||
uv_sem_wait(&start_sem_);
|
uv_sem_wait(&start_sem_);
|
||||||
|
|
||||||
@ -606,6 +608,7 @@ void AgentImpl::PostIncomingMessage(InspectorAction action, int session_id,
|
|||||||
platform_->CallOnForegroundThread(isolate,
|
platform_->CallOnForegroundThread(isolate,
|
||||||
new DispatchOnInspectorBackendTask(this));
|
new DispatchOnInspectorBackendTask(this));
|
||||||
isolate->RequestInterrupt(InterruptCallback, this);
|
isolate->RequestInterrupt(InterruptCallback, this);
|
||||||
|
CHECK_EQ(0, uv_async_send(&main_thread_req_));
|
||||||
}
|
}
|
||||||
NotifyMessageReceived();
|
NotifyMessageReceived();
|
||||||
}
|
}
|
||||||
@ -662,6 +665,12 @@ void AgentImpl::DispatchMessages() {
|
|||||||
dispatching_messages_ = false;
|
dispatching_messages_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void AgentImpl::MainThreadAsyncCb(uv_async_t* req) {
|
||||||
|
AgentImpl* agent = node::ContainerOf(&AgentImpl::main_thread_req_, req);
|
||||||
|
agent->DispatchMessages();
|
||||||
|
}
|
||||||
|
|
||||||
void AgentImpl::Write(TransportAction action, int session_id,
|
void AgentImpl::Write(TransportAction action, int session_id,
|
||||||
const StringView& inspector_message) {
|
const StringView& inspector_message) {
|
||||||
AppendMessage(&outgoing_message_queue_, action, session_id,
|
AppendMessage(&outgoing_message_queue_, action, session_id,
|
||||||
|
@ -427,9 +427,24 @@ Harness.prototype.expectShutDown = function(errorCode) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.startNodeForInspectorTest = function(callback) {
|
Harness.prototype.kill = function() {
|
||||||
const child = spawn(process.execPath,
|
return this.enqueue_((callback) => {
|
||||||
[ '--inspect-brk', mainScript ]);
|
this.process_.kill();
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.startNodeForInspectorTest = function(callback,
|
||||||
|
inspectorFlag = '--inspect-brk',
|
||||||
|
opt_script_contents) {
|
||||||
|
const args = [inspectorFlag];
|
||||||
|
if (opt_script_contents) {
|
||||||
|
args.push('-e', opt_script_contents);
|
||||||
|
} else {
|
||||||
|
args.push(mainScript);
|
||||||
|
}
|
||||||
|
|
||||||
|
const child = spawn(process.execPath, args);
|
||||||
|
|
||||||
const timeoutId = timeout('Child process did not start properly', 4);
|
const timeoutId = timeout('Child process did not start properly', 4);
|
||||||
|
|
||||||
|
20
test/inspector/test-not-blocked-on-idle.js
Normal file
20
test/inspector/test-not-blocked-on-idle.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
'use strict';
|
||||||
|
require('../common');
|
||||||
|
const helper = require('./inspector-helper.js');
|
||||||
|
|
||||||
|
function shouldShutDown(session) {
|
||||||
|
session
|
||||||
|
.sendInspectorCommands([
|
||||||
|
{ 'method': 'Debugger.enable' },
|
||||||
|
{ 'method': 'Debugger.pause' },
|
||||||
|
])
|
||||||
|
.disconnect(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests(harness) {
|
||||||
|
// 1 second wait to make sure the inferior began running the script
|
||||||
|
setTimeout(() => harness.runFrontendSession([shouldShutDown]).kill(), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
const script = 'setInterval(() => {debugger;}, 60000);';
|
||||||
|
helper.startNodeForInspectorTest(runTests, '--inspect', script);
|
Loading…
x
Reference in New Issue
Block a user