1'use strict';
2const common = require('../common');
3const assert = require('assert');
4const { once } = require('events');
5const { Worker, MessageChannel } = require('worker_threads');
6
7// This is a regression test for the race condition underlying
8// https://github.com/nodejs/node/issues/22762.
9// It ensures that all messages send before a MessagePort#close() call are
10// received. Previously, what could happen was a race condition like this:
11// - Thread 1 sends message A
12// - Thread 2 begins receiving/emitting message A
13// - Thread 1 sends message B
14// - Thread 1 closes its side of the channel
15// - Thread 2 finishes receiving/emitting message A
16// - Thread 2 sees that the port should be closed
17// - Thread 2 closes the port, discarding message B in the process.
18
19async function test() {
20  const worker = new Worker(`
21  require('worker_threads').parentPort.on('message', ({ port }) => {
22    port.postMessage('firstMessage');
23    port.postMessage('lastMessage');
24    port.close();
25  });
26  `, { eval: true });
27
28  for (let i = 0; i < 10000; i++) {
29    const { port1, port2 } = new MessageChannel();
30    worker.postMessage({ port: port2 }, [ port2 ]);
31    assert.deepStrictEqual(await once(port1, 'message'), ['firstMessage']);
32    assert.deepStrictEqual(await once(port1, 'message'), ['lastMessage']);
33  }
34
35  await worker.terminate();
36}
37
38test().then(common.mustCall());
39