Skip to content

Commit f26a4d0

Browse files
BridgeARcodebytere
andcommitted
lib: do not crash using workers with disabled shared array buffers
This allows the repl to function normally while using the `--no-harmony-sharedarraybuffer` V8 flag. Fixes: #39717 Signed-off-by: Ruben Bridgewater <[email protected]> Co-authored-by: Shelley Vohr <[email protected]>
1 parent 18ff583 commit f26a4d0

File tree

4 files changed

+47
-16
lines changed

4 files changed

+47
-16
lines changed

benchmark/worker/atomics-wait.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
'use strict';
22
/* global SharedArrayBuffer */
33

4+
if (typeof SharedArrayBuffer === 'undefined') {
5+
throw new Error('SharedArrayBuffers must be enabled to run this benchmark');
6+
}
7+
48
const common = require('../common.js');
59
const bench = common.createBenchmark(main, {
610
n: [1e7]

lib/internal/main/worker_thread.js

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ const {
99
ArrayPrototypeSplice,
1010
ObjectDefineProperty,
1111
PromisePrototypeCatch,
12-
globalThis: { Atomics },
12+
globalThis: {
13+
Atomics,
14+
SharedArrayBuffer
15+
},
1316
} = primordials;
1417

1518
const {
@@ -135,21 +138,23 @@ port.on('message', (message) => {
135138

136139
require('internal/worker').assignEnvironmentData(environmentData);
137140

138-
// The counter is only passed to the workers created by the main thread, not
139-
// to workers created by other workers.
140-
let cachedCwd = '';
141-
let lastCounter = -1;
142-
const originalCwd = process.cwd;
143-
144-
process.cwd = function() {
145-
const currentCounter = Atomics.load(cwdCounter, 0);
146-
if (currentCounter === lastCounter)
141+
if (typeof SharedArrayBuffer !== 'undefined') {
142+
// The counter is only passed to the workers created by the main thread,
143+
// not to workers created by other workers.
144+
let cachedCwd = '';
145+
let lastCounter = -1;
146+
const originalCwd = process.cwd;
147+
148+
process.cwd = function() {
149+
const currentCounter = Atomics.load(cwdCounter, 0);
150+
if (currentCounter === lastCounter)
151+
return cachedCwd;
152+
lastCounter = currentCounter;
153+
cachedCwd = originalCwd();
147154
return cachedCwd;
148-
lastCounter = currentCounter;
149-
cachedCwd = originalCwd();
150-
return cachedCwd;
151-
};
152-
workerIo.sharedCwdCounter = cwdCounter;
155+
};
156+
workerIo.sharedCwdCounter = cwdCounter;
157+
}
153158

154159
const CJSLoader = require('internal/modules/cjs/loader');
155160
assert(!CJSLoader.hasLoadedAnyUserCJSModule);

lib/internal/worker.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ let cwdCounter;
9090

9191
const environmentData = new SafeMap();
9292

93-
if (isMainThread) {
93+
// SharedArrayBuffers can be disabled with --no-harmony-sharedarraybuffer.
94+
if (isMainThread && typeof SharedArrayBuffer !== 'undefined') {
9495
cwdCounter = new Uint32Array(new SharedArrayBuffer(4));
9596
const originalChdir = process.chdir;
9697
process.chdir = function(path) {

test/parallel/test-worker-no-sab.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Flags: --no-harmony-sharedarraybuffer
2+
3+
'use strict';
4+
5+
const common = require('../common');
6+
const assert = require('assert');
7+
const { Worker } = require('worker_threads');
8+
9+
// Regression test for https://github.com/nodejs/node/issues/39717.
10+
11+
// Do not use isMainThread so that this test itself can be run inside a Worker.
12+
if (!process.env.HAS_STARTED_WORKER) {
13+
process.env.HAS_STARTED_WORKER = 1;
14+
const w = new Worker(__filename);
15+
16+
w.on('exit', common.mustCall((status) => {
17+
assert.strictEqual(status, 2);
18+
}));
19+
} else {
20+
process.exit(2);
21+
}

0 commit comments

Comments
 (0)