• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const common = require('../common');
3const assert = require('assert');
4const fs = require('fs').promises;
5const vm = require('vm');
6const { MessageChannel, moveMessagePortToContext } = require('worker_threads');
7const { once } = require('events');
8
9(async function() {
10  const fh = await fs.open(__filename);
11
12  const { port1, port2 } = new MessageChannel();
13
14  assert.throws(() => {
15    port1.postMessage(fh);
16  }, {
17    // See the TODO about error code in node_messaging.cc.
18    code: 'ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST'
19  });
20
21  // Check that transferring FileHandle instances works.
22  assert.notStrictEqual(fh.fd, -1);
23  port1.postMessage(fh, [ fh ]);
24  assert.strictEqual(fh.fd, -1);
25
26  const [ fh2 ] = await once(port2, 'message');
27  assert.strictEqual(Object.getPrototypeOf(fh2), Object.getPrototypeOf(fh));
28
29  assert.deepStrictEqual(await fh2.readFile(), await fs.readFile(__filename));
30  await fh2.close();
31
32  assert.rejects(() => fh.readFile(), { code: 'EBADF' });
33})().then(common.mustCall());
34
35(async function() {
36  // Check that there is no crash if the message is never read.
37  const fh = await fs.open(__filename);
38
39  const { port1 } = new MessageChannel();
40
41  assert.notStrictEqual(fh.fd, -1);
42  port1.postMessage(fh, [ fh ]);
43  assert.strictEqual(fh.fd, -1);
44})().then(common.mustCall());
45
46(async function() {
47  // Check that in the case of a context mismatch the message is discarded.
48  const fh = await fs.open(__filename);
49
50  const { port1, port2 } = new MessageChannel();
51
52  const ctx = vm.createContext();
53  const port2moved = moveMessagePortToContext(port2, ctx);
54  port2moved.onmessage = common.mustCall((msgEvent) => {
55    assert.strictEqual(msgEvent.data, 'second message');
56    port1.close();
57  });
58  // TODO(addaleax): Switch this to a 'messageerror' event once MessagePort
59  // implements EventTarget fully and in a cross-context manner.
60  port2moved.emit = common.mustCall((name, err) => {
61    assert.strictEqual(name, 'messageerror');
62    assert.strictEqual(err.code, 'ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE');
63  });
64  port2moved.start();
65
66  assert.notStrictEqual(fh.fd, -1);
67  port1.postMessage(fh, [ fh ]);
68  assert.strictEqual(fh.fd, -1);
69
70  port1.postMessage('second message');
71})().then(common.mustCall());
72