• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4const assert = require('assert');
5const { MessageChannel } = require('worker_threads');
6
7// This tests various behaviors around transferring MessagePorts with closing
8// or closed handles.
9
10const { port1, port2 } = new MessageChannel();
11
12const arrayBuf = new ArrayBuffer(10);
13port1.onmessage = common.mustNotCall();
14port2.onmessage = common.mustNotCall();
15
16function testSingle(closedPort, potentiallyOpenPort) {
17  assert.throws(common.mustCall(() => {
18    potentiallyOpenPort.postMessage(null, [arrayBuf, closedPort]);
19  }), common.mustCall((err) => {
20    assert.strictEqual(err.name, 'DataCloneError');
21    assert.strictEqual(err.message,
22                       'MessagePort in transfer list is already detached');
23    assert.strictEqual(err.code, 25);
24    assert.ok(err instanceof Error);
25
26    const DOMException = err.constructor;
27    assert.ok(err instanceof DOMException);
28    assert.strictEqual(DOMException.name, 'DOMException');
29
30    return true;
31  }));
32
33  // arrayBuf must not be transferred, even though it is present earlier in the
34  // transfer list than the closedPort.
35  assert.strictEqual(arrayBuf.byteLength, 10);
36}
37
38function testBothClosed() {
39  testSingle(port1, port2);
40  testSingle(port2, port1);
41}
42
43// Even though the port handles may not be completely closed in C++ land, the
44// observable behavior must be that the closing/detachment is synchronous and
45// instant.
46
47port1.close(common.mustCall(testBothClosed));
48testSingle(port1, port2);
49port2.close(common.mustCall(testBothClosed));
50testBothClosed();
51
52function tickUnref(n, fn) {
53  if (n === 0) return fn();
54  setImmediate(tickUnref, n - 1, fn).unref();
55}
56
57tickUnref(10, common.mustNotCall('The communication channel is still open'));
58