Skip to content

Commit afb4279

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: nodejs#39717 Signed-off-by: Ruben Bridgewater <[email protected]> Co-authored-by: Shelley Vohr <[email protected]>
1 parent d96a2ea commit afb4279

File tree

4 files changed

+52
-17
lines changed

4 files changed

+52
-17
lines changed

benchmark/worker/atomics-wait.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
'use strict';
2-
/* global SharedArrayBuffer */
2+
3+
if (typeof SharedArrayBuffer === 'undefined') {
4+
throw new Error('SharedArrayBuffers must be enabled to run this benchmark');
5+
}
6+
7+
if (typeof Atomics === 'undefined') {
8+
throw new Error('Atomics must be enabled to run this benchmark');
9+
}
310

411
const common = require('../common.js');
512
const bench = common.createBenchmark(main, {

lib/internal/main/worker_thread.js

+20-15
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 {
@@ -141,21 +144,23 @@ port.on('message', (message) => {
141144

142145
require('internal/worker').assignEnvironmentData(environmentData);
143146

144-
// The counter is only passed to the workers created by the main thread, not
145-
// to workers created by other workers.
146-
let cachedCwd = '';
147-
let lastCounter = -1;
148-
const originalCwd = process.cwd;
149-
150-
process.cwd = function() {
151-
const currentCounter = Atomics.load(cwdCounter, 0);
152-
if (currentCounter === lastCounter)
147+
if (SharedArrayBuffer !== undefined && Atomics !== undefined) {
148+
// The counter is only passed to the workers created by the main thread,
149+
// not to workers created by other workers.
150+
let cachedCwd = '';
151+
let lastCounter = -1;
152+
const originalCwd = process.cwd;
153+
154+
process.cwd = function() {
155+
const currentCounter = Atomics.load(cwdCounter, 0);
156+
if (currentCounter === lastCounter)
157+
return cachedCwd;
158+
lastCounter = currentCounter;
159+
cachedCwd = originalCwd();
153160
return cachedCwd;
154-
lastCounter = currentCounter;
155-
cachedCwd = originalCwd();
156-
return cachedCwd;
157-
};
158-
workerIo.sharedCwdCounter = cwdCounter;
161+
};
162+
workerIo.sharedCwdCounter = cwdCounter;
163+
}
159164

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

lib/internal/worker.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ let cwdCounter;
9191

9292
const environmentData = new SafeMap();
9393

94-
if (isMainThread) {
94+
// SharedArrayBuffers can be disabled with --no-harmony-sharedarraybuffer.
95+
// Atomics can be disabled with --no-harmony-atomics.
96+
if (isMainThread && SharedArrayBuffer !== undefined && Atomics !== undefined) {
9597
cwdCounter = new Uint32Array(new SharedArrayBuffer(4));
9698
const originalChdir = process.chdir;
9799
process.chdir = function(path) {

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

+21
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)