Skip to content

Commit

Permalink
src: handling v8 thread pool of zero
Browse files Browse the repository at this point in the history
fix: nodejs#42523

Problem:
If no platform worker exists, Node.js doesn't shut down when background
tasks exist. It keeps waiting in `NodePlatform::DrainTasks`.

Observation:
It seems that Node.js used to use V8's `DefaultPlatform` implementation,
which chooses a suitable default value in case that `--v8-pool-size=0`
is given as a command-line option. However, Node.js currently uses its
own v8::Platform implementation, `NodePlatform`. It doesn't have the
logic to handle the case.

I referred to nodejs#4344 to track the issue.
  • Loading branch information
daeyeon committed Mar 30, 2022
1 parent 33cbdb3 commit 9fd2df7
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
4 changes: 1 addition & 3 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -1368,11 +1368,9 @@ added: v5.10.0

Set V8's thread pool size which will be used to allocate background jobs.

If set to `0` then V8 will choose an appropriate size of the thread pool based
If set to `0` then Node.js will choose an appropriate size of the thread pool based
on the number of online processors.

If the value provided is larger than V8's maximum, then the largest value
will be chosen.

### `--zero-fill-buffers`

Expand Down
15 changes: 15 additions & 0 deletions src/node_platform.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ static void PlatformWorkerThread(void* data) {
}
}

static int GetActualThreadPoolSize(int thread_pool_size) {
if (thread_pool_size < 1) {
uv_cpu_info_t* cpu_info;
int count;

if (uv_cpu_info(&cpu_info, &count) == 0) {
uv_free_cpu_info(cpu_info, count);
thread_pool_size = count - 1;
}
}
return std::max(thread_pool_size, 1);
}

} // namespace

class WorkerThreadsTaskRunner::DelayedTaskScheduler {
Expand Down Expand Up @@ -340,6 +353,8 @@ NodePlatform::NodePlatform(int thread_pool_size,
// current v8::Platform instance.
SetTracingController(tracing_controller_);
DCHECK_EQ(GetTracingController(), tracing_controller_);

thread_pool_size = GetActualThreadPoolSize(thread_pool_size);
worker_thread_task_runner_ =
std::make_shared<WorkerThreadsTaskRunner>(thread_pool_size);
}
Expand Down
15 changes: 15 additions & 0 deletions test/parallel/test-worker-v8-pool-size-0.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Flags: --v8-pool-size=0
'use strict';

const common = require('../common');
const assert = require('assert');
const { Worker, isMainThread } = require('worker_threads');

if (isMainThread) {
const w = new Worker(__filename);
w.on('online', common.mustCall());
w.on('exit', common.mustCall((code) => assert.strictEqual(code, 0)));
process.on('exit', (code) => {
assert.strictEqual(code, 0);
});
}

0 comments on commit 9fd2df7

Please sign in to comment.