Skip to content

Commit 8cb5e41

Browse files
juanarboltargos
authored andcommitted
worker: support MessagePort to workers data
PR-URL: #32278 Fixes: #32250 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 8f0c106 commit 8cb5e41

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

doc/api/worker_threads.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,9 @@ if (isMainThread) {
513513
<!-- YAML
514514
added: v10.5.0
515515
changes:
516+
- version: REPLACEME
517+
pr-url: https://github.com/nodejs/node/pull/32278
518+
description: The `transferList` option was introduced.
516519
- version: v13.12.0
517520
pr-url: https://github.com/nodejs/node/pull/31664
518521
description: The `filename` parameter can be a WHATWG `URL` object using

lib/internal/worker.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ class Worker extends EventEmitter {
183183
this[kParentSideStdio] = { stdin, stdout, stderr };
184184

185185
const { port1, port2 } = new MessageChannel();
186+
const transferList = [port2];
187+
// If transferList is provided.
188+
if (options.transferList)
189+
transferList.push(...options.transferList);
190+
186191
this[kPublicPort] = port1;
187192
this[kPublicPort].on('message', (message) => this.emit('message', message));
188193
setupPortReferencing(this[kPublicPort], this, 'message');
@@ -198,7 +203,7 @@ class Worker extends EventEmitter {
198203
require('internal/process/policy').src :
199204
null,
200205
hasStdin: !!options.stdin
201-
}, [port2]);
206+
}, transferList);
202207
// Actually start the new thread now that everything is in place.
203208
this[kHandle].startThread();
204209
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'use strict';
2+
3+
require('../common');
4+
const assert = require('assert');
5+
6+
const {
7+
Worker, MessageChannel
8+
} = require('worker_threads');
9+
10+
const channel = new MessageChannel();
11+
const workerData = { mesage: channel.port1 };
12+
const transferList = [channel.port1];
13+
const meowScript = () => 'meow';
14+
15+
{
16+
// Should receive the transferList param.
17+
new Worker(`${meowScript}`, { eval: true, workerData, transferList });
18+
}
19+
20+
{
21+
// Should work with more than one MessagePort.
22+
const channel1 = new MessageChannel();
23+
const channel2 = new MessageChannel();
24+
const workerData = { message: channel1.port1, message2: channel2.port1 };
25+
const transferList = [channel1.port1, channel2.port1];
26+
new Worker(`${meowScript}`, { eval: true, workerData, transferList });
27+
}
28+
29+
{
30+
const uint8Array = new Uint8Array([ 1, 2, 3, 4 ]);
31+
assert.deepStrictEqual(uint8Array.length, 4);
32+
new Worker(`
33+
const { parentPort, workerData } = require('worker_threads');
34+
parentPort.postMessage(workerData);
35+
`, {
36+
eval: true,
37+
workerData: uint8Array,
38+
transferList: [uint8Array.buffer]
39+
}).on(
40+
'message',
41+
(message) =>
42+
assert.deepStrictEqual(message, Uint8Array.of(1, 2, 3, 4))
43+
);
44+
assert.deepStrictEqual(uint8Array.length, 0);
45+
}
46+
47+
{
48+
// Should throw on non valid transferList input.
49+
const channel1 = new MessageChannel();
50+
const channel2 = new MessageChannel();
51+
const workerData = { message: channel1.port1, message2: channel2.port1 };
52+
assert.throws(() => new Worker(`${meowScript}`, {
53+
eval: true,
54+
workerData,
55+
transferList: []
56+
}), {
57+
code: 'ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST',
58+
message: 'MessagePort was found in message but not listed in transferList'
59+
});
60+
}

0 commit comments

Comments
 (0)