Skip to content

Commit cf16123

Browse files
Ceres6aduh95
authored andcommitted
src,worker: add isInternalWorker
PR-URL: #56469 Reviewed-By: Jacob Smith <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Bryan English <[email protected]>
1 parent f54118c commit cf16123

File tree

8 files changed

+104
-4
lines changed

8 files changed

+104
-4
lines changed

‎doc/api/worker_threads.md‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,44 @@ if (isMainThread){
100100
}
101101
```
102102

103+
## `worker.isInternalThread`
104+
105+
<!-- YAML
106+
added: REPLACEME
107+
-->
108+
109+
*{boolean}
110+
111+
Is `true` if this code is running inside of an internal [`Worker`][] thread (e.g the loader thread).
112+
113+
```bash
114+
node --experimental-loader ./loader.js main.js
115+
```
116+
117+
```cjs
118+
// loader.js
119+
const{isInternalThread } =require('node:worker_threads');
120+
console.log(isInternalThread); // true
121+
```
122+
123+
```mjs
124+
// loader.js
125+
import{isInternalThread } from'node:worker_threads';
126+
console.log(isInternalThread); // true
127+
```
128+
129+
```cjs
130+
// main.js
131+
const{isInternalThread } =require('node:worker_threads');
132+
console.log(isInternalThread); // false
133+
```
134+
135+
```mjs
136+
// main.js
137+
import{isInternalThread } from'node:worker_threads';
138+
console.log(isInternalThread); // false
139+
```
140+
103141
## `worker.isMainThread`
104142

105143
<!-- YAML

‎lib/internal/worker.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ const{
6767
const{
6868
ownsProcessState,
6969
isMainThread,
70+
isInternalThread,
7071
resourceLimits: resourceLimitsRaw,
7172
threadId,
7273
Worker: WorkerImpl,
@@ -538,6 +539,7 @@ module.exports ={
538539
ownsProcessState,
539540
kIsOnline,
540541
isMainThread,
542+
isInternalThread,
541543
SHARE_ENV,
542544
resourceLimits:
543545
!isMainThread ? makeResourceLimits(resourceLimitsRaw) : {},

‎lib/worker_threads.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const{
4+
isInternalThread,
45
isMainThread,
56
SHARE_ENV,
67
resourceLimits,
@@ -29,6 +30,7 @@ const{
2930
}=require('internal/buffer');
3031

3132
module.exports={
33+
isInternalThread,
3234
isMainThread,
3335
MessagePort,
3436
MessageChannel,

‎src/node_worker.cc‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ Worker::Worker(Environment* env,
5454
std::shared_ptr<PerIsolateOptions> per_isolate_opts,
5555
std::vector<std::string>&& exec_argv,
5656
std::shared_ptr<KVStore> env_vars,
57-
const SnapshotData* snapshot_data)
57+
const SnapshotData* snapshot_data,
58+
constbool is_internal)
5859
: AsyncWrap(env, wrap, AsyncWrap::PROVIDER_WORKER),
5960
per_isolate_opts_(per_isolate_opts),
6061
exec_argv_(exec_argv),
@@ -63,7 +64,8 @@ Worker::Worker(Environment* env,
6364
name_(name),
6465
env_vars_(env_vars),
6566
embedder_preload_(env->embedder_preload()),
66-
snapshot_data_(snapshot_data){
67+
snapshot_data_(snapshot_data),
68+
is_internal_(is_internal){
6769
Debug(this, "Creating new worker instance with thread id %llu",
6870
thread_id_.id);
6971

@@ -685,7 +687,8 @@ void Worker::New(const FunctionCallbackInfo<Value>& args){
685687
per_isolate_opts,
686688
std::move(exec_argv_out),
687689
env_vars,
688-
snapshot_data);
690+
snapshot_data,
691+
is_internal);
689692

690693
CHECK(args[3]->IsFloat64Array());
691694
Local<Float64Array> limit_info = args[3].As<Float64Array>();
@@ -1028,6 +1031,16 @@ void CreateWorkerPerContextProperties(Local<Object> target,
10281031
Boolean::New(isolate, env->is_main_thread()))
10291032
.Check();
10301033

1034+
Worker* worker = env->isolate_data()->worker_context();
1035+
bool is_internal = worker != nullptr && worker->is_internal();
1036+
1037+
// Set the is_internal property
1038+
target
1039+
->Set(env->context(),
1040+
FIXED_ONE_BYTE_STRING(isolate, "isInternalThread"),
1041+
Boolean::New(isolate, is_internal))
1042+
.Check();
1043+
10311044
target
10321045
->Set(env->context(),
10331046
FIXED_ONE_BYTE_STRING(isolate, "ownsProcessState"),

‎src/node_worker.h‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ class Worker : public AsyncWrap{
3434
std::shared_ptr<PerIsolateOptions> per_isolate_opts,
3535
std::vector<std::string>&& exec_argv,
3636
std::shared_ptr<KVStore> env_vars,
37-
const SnapshotData* snapshot_data);
37+
const SnapshotData* snapshot_data,
38+
constbool is_internal);
3839
~Worker() override;
3940

4041
// Run the worker. This is only called from the worker thread.
@@ -60,6 +61,7 @@ class Worker : public AsyncWrap{
6061

6162
boolis_stopped() const;
6263
const SnapshotData* snapshot_data() const{return snapshot_data_}
64+
boolis_internal() const{return is_internal_}
6365

6466
staticvoidNew(const v8::FunctionCallbackInfo<v8::Value>& args);
6567
staticvoidCloneParentEnvVars(
@@ -132,6 +134,7 @@ class Worker : public AsyncWrap{
132134
Environment* env_ = nullptr;
133135

134136
const SnapshotData* snapshot_data_ = nullptr;
137+
constbool is_internal_;
135138
friendclassWorkerThreadData;
136139
};
137140

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const{ isInternalThread }=require('node:worker_threads');
2+
3+
console.log(`isInternalThread: ${isInternalThread}`);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const{ isInternalThread, parentPort }=require('node:worker_threads');
2+
3+
parentPort.postMessage(`isInternalThread: ${isInternalThread}`);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import{spawnPromisified}from'../common/index.mjs';
2+
import*asfixturesfrom'../common/fixtures.mjs';
3+
importassertfrom'node:assert';
4+
import{execPath}from'node:process';
5+
import{describe,it}from'node:test';
6+
import{isInternalThread,Worker}from'node:worker_threads';
7+
import*ascommonfrom'../common/index.mjs';
8+
9+
describe('worker_threads.isInternalThread',{concurrency: !process.env.TEST_PARALLEL},()=>{
10+
it('should be true inside the loader thread',async()=>{
11+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
12+
'--no-warnings',
13+
'--experimental-loader',
14+
fixtures.fileURL('loader-is-internal-thread.js'),
15+
'--eval',
16+
'setTimeout(() =>{},99)',
17+
]);
18+
19+
assert.strictEqual(stderr,'');
20+
assert.match(stdout,/isInternalThread:true/);
21+
assert.strictEqual(code,0);
22+
assert.strictEqual(signal,null);
23+
});
24+
25+
it('should be false inside the main thread',async()=>{
26+
assert.strictEqual(isInternalThread,false);
27+
});
28+
29+
it('should be false inside a regular worker thread',async()=>{
30+
constworker=newWorker(fixtures.path('worker-is-internal-thread.js'));
31+
32+
worker.on('message',common.mustCall((message)=>{
33+
assert.strictEqual(message,'isInternalThread: false');
34+
}));
35+
});
36+
});

0 commit comments

Comments
(0)