11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ciconst assert = require('assert'); 51cb0ef41Sopenharmony_ciconst { MessageChannel } = require('worker_threads'); 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci// This tests various behaviors around transferring MessagePorts with closing 81cb0ef41Sopenharmony_ci// or closed handles. 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ciconst { port1, port2 } = new MessageChannel(); 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ciconst arrayBuf = new ArrayBuffer(10); 131cb0ef41Sopenharmony_ciport1.onmessage = common.mustNotCall(); 141cb0ef41Sopenharmony_ciport2.onmessage = common.mustNotCall(); 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_cifunction testSingle(closedPort, potentiallyOpenPort) { 171cb0ef41Sopenharmony_ci assert.throws(common.mustCall(() => { 181cb0ef41Sopenharmony_ci potentiallyOpenPort.postMessage(null, [arrayBuf, closedPort]); 191cb0ef41Sopenharmony_ci }), common.mustCall((err) => { 201cb0ef41Sopenharmony_ci assert.strictEqual(err.name, 'DataCloneError'); 211cb0ef41Sopenharmony_ci assert.strictEqual(err.message, 221cb0ef41Sopenharmony_ci 'MessagePort in transfer list is already detached'); 231cb0ef41Sopenharmony_ci assert.strictEqual(err.code, 25); 241cb0ef41Sopenharmony_ci assert.ok(err instanceof Error); 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci const DOMException = err.constructor; 271cb0ef41Sopenharmony_ci assert.ok(err instanceof DOMException); 281cb0ef41Sopenharmony_ci assert.strictEqual(DOMException.name, 'DOMException'); 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci return true; 311cb0ef41Sopenharmony_ci })); 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci // arrayBuf must not be transferred, even though it is present earlier in the 341cb0ef41Sopenharmony_ci // transfer list than the closedPort. 351cb0ef41Sopenharmony_ci assert.strictEqual(arrayBuf.byteLength, 10); 361cb0ef41Sopenharmony_ci} 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_cifunction testBothClosed() { 391cb0ef41Sopenharmony_ci testSingle(port1, port2); 401cb0ef41Sopenharmony_ci testSingle(port2, port1); 411cb0ef41Sopenharmony_ci} 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci// Even though the port handles may not be completely closed in C++ land, the 441cb0ef41Sopenharmony_ci// observable behavior must be that the closing/detachment is synchronous and 451cb0ef41Sopenharmony_ci// instant. 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ciport1.close(common.mustCall(testBothClosed)); 481cb0ef41Sopenharmony_citestSingle(port1, port2); 491cb0ef41Sopenharmony_ciport2.close(common.mustCall(testBothClosed)); 501cb0ef41Sopenharmony_citestBothClosed(); 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_cifunction tickUnref(n, fn) { 531cb0ef41Sopenharmony_ci if (n === 0) return fn(); 541cb0ef41Sopenharmony_ci setImmediate(tickUnref, n - 1, fn).unref(); 551cb0ef41Sopenharmony_ci} 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_citickUnref(10, common.mustNotCall('The communication channel is still open')); 58