Skip to content

Commit eeaceff

Browse files
marvinhagemeisterdsherret
authored andcommitted
fix(node/worker_threads): support port.once() (#24725)
Support `MessagePort.once` in Node mode and enable relevant `worker_threads` test. Noticed that another Node test was passing as well, so I enabled that too.
1 parent 2a026be commit eeaceff

File tree

5 files changed

+69
-2
lines changed

5 files changed

+69
-2
lines changed

ext/node/polyfills/worker_threads.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,13 @@ function webMessagePortToNodeMessagePort(port: MessagePort) {
536536
port.ref = () => {
537537
port[refMessagePort](true);
538538
};
539+
port.once = (name: string | symbol, listener) => {
540+
const fn = (event) => {
541+
port.off(name, fn);
542+
return listener(event);
543+
};
544+
port.on(name, fn);
545+
};
539546
return port;
540547
}
541548

tests/node_compat/config.jsonc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,8 @@
684684
"test-whatwg-url-custom-tostringtag.js",
685685
"test-whatwg-url-override-hostname.js",
686686
"test-whatwg-url-properties.js",
687+
"test-worker-message-port-infinite-message-loop.js",
688+
"test-worker-message-port-multiple-sharedarraybuffers.js",
687689
"test-worker-message-port-receive-message.js",
688690
"test-zlib-close-after-error.js",
689691
"test-zlib-close-after-write.js",

tests/node_compat/runner/TODO.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2829,13 +2829,11 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co
28292829
- [parallel/test-worker-message-port-close.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-close.js)
28302830
- [parallel/test-worker-message-port-constructor.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-constructor.js)
28312831
- [parallel/test-worker-message-port-drain.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-drain.js)
2832-
- [parallel/test-worker-message-port-infinite-message-loop.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-infinite-message-loop.js)
28332832
- [parallel/test-worker-message-port-inspect-during-init-hook.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-inspect-during-init-hook.js)
28342833
- [parallel/test-worker-message-port-jstransferable-nested-untransferable.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-jstransferable-nested-untransferable.js)
28352834
- [parallel/test-worker-message-port-message-before-close.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-message-before-close.js)
28362835
- [parallel/test-worker-message-port-message-port-transferring.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-message-port-transferring.js)
28372836
- [parallel/test-worker-message-port-move.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-move.js)
2838-
- [parallel/test-worker-message-port-multiple-sharedarraybuffers.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-multiple-sharedarraybuffers.js)
28392837
- [parallel/test-worker-message-port-terminate-transfer-list.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-terminate-transfer-list.js)
28402838
- [parallel/test-worker-message-port-transfer-closed.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-transfer-closed.js)
28412839
- [parallel/test-worker-message-port-transfer-duplicate.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-transfer-duplicate.js)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// deno-fmt-ignore-file
2+
// deno-lint-ignore-file
3+
4+
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
5+
// Taken from Node 18.12.1
6+
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
7+
8+
'use strict';
9+
const common = require('../common');
10+
const assert = require('assert');
11+
12+
const { MessageChannel } = require('worker_threads');
13+
14+
// Make sure that an infinite asynchronous .on('message')/postMessage loop
15+
// does not lead to a stack overflow and does not starve the event loop.
16+
// We schedule timeouts both from before the .on('message') handler and
17+
// inside of it, which both should run.
18+
19+
const { port1, port2 } = new MessageChannel();
20+
let count = 0;
21+
port1.on('message', () => {
22+
if (count === 0) {
23+
setTimeout(common.mustCall(() => {
24+
port1.close();
25+
}), 0);
26+
}
27+
28+
port2.postMessage(0);
29+
assert(count++ < 10000, `hit ${count} loop iterations`);
30+
});
31+
32+
port2.postMessage(0);
33+
34+
// This is part of the test -- the event loop should be available and not stall
35+
// out due to the recursive .postMessage() calls.
36+
setTimeout(common.mustCall(), 0);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// deno-fmt-ignore-file
2+
// deno-lint-ignore-file
3+
4+
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
5+
// Taken from Node 18.12.1
6+
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
7+
8+
'use strict';
9+
const common = require('../common');
10+
const assert = require('assert');
11+
const { MessageChannel } = require('worker_threads');
12+
13+
// Regression test for https://github.com/nodejs/node/issues/28559
14+
15+
const obj = [
16+
[ new SharedArrayBuffer(0), new SharedArrayBuffer(1) ],
17+
[ new SharedArrayBuffer(2), new SharedArrayBuffer(3) ],
18+
];
19+
20+
const { port1, port2 } = new MessageChannel();
21+
port1.once('message', common.mustCall((message) => {
22+
assert.deepStrictEqual(message, obj);
23+
}));
24+
port2.postMessage(obj);

0 commit comments

Comments
 (0)