11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ciconst { ok, strictEqual } = require('assert'); 51cb0ef41Sopenharmony_ciconst { setImmediate: pause } = require('timers/promises'); 61cb0ef41Sopenharmony_ciconst { 71cb0ef41Sopenharmony_ci transferableAbortSignal, 81cb0ef41Sopenharmony_ci transferableAbortController, 91cb0ef41Sopenharmony_ci} = require('util'); 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_cifunction deferred() { 131cb0ef41Sopenharmony_ci let res; 141cb0ef41Sopenharmony_ci const promise = new Promise((resolve) => res = resolve); 151cb0ef41Sopenharmony_ci return { res, promise }; 161cb0ef41Sopenharmony_ci} 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ci(async () => { 191cb0ef41Sopenharmony_ci const ac = transferableAbortController(); 201cb0ef41Sopenharmony_ci const mc = new MessageChannel(); 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci const deferred1 = deferred(); 231cb0ef41Sopenharmony_ci const deferred2 = deferred(); 241cb0ef41Sopenharmony_ci const resolvers = [deferred1, deferred2]; 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci mc.port1.onmessage = common.mustCall(({ data }) => { 271cb0ef41Sopenharmony_ci data.addEventListener('abort', common.mustCall(() => { 281cb0ef41Sopenharmony_ci strictEqual(data.reason, 'boom'); 291cb0ef41Sopenharmony_ci })); 301cb0ef41Sopenharmony_ci resolvers.shift().res(); 311cb0ef41Sopenharmony_ci }, 2); 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci mc.port2.postMessage(ac.signal, [ac.signal]); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci // Can be cloned/transferd multiple times and they all still work 361cb0ef41Sopenharmony_ci mc.port2.postMessage(ac.signal, [ac.signal]); 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci mc.port2.close(); 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci // Although we're using transfer semantics, the local AbortSignal 411cb0ef41Sopenharmony_ci // is still usable locally. 421cb0ef41Sopenharmony_ci ac.signal.addEventListener('abort', common.mustCall(() => { 431cb0ef41Sopenharmony_ci strictEqual(ac.signal.reason, 'boom'); 441cb0ef41Sopenharmony_ci })); 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci await Promise.all([ deferred1.promise, deferred2.promise ]); 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci ac.abort('boom'); 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci // Because the postMessage used by the underlying AbortSignal 511cb0ef41Sopenharmony_ci // takes at least one turn of the event loop to be processed, 521cb0ef41Sopenharmony_ci // and because it is unref'd, it won't, by itself, keep the 531cb0ef41Sopenharmony_ci // event loop open long enough for the test to complete, so 541cb0ef41Sopenharmony_ci // we schedule two back to back turns of the event to ensure 551cb0ef41Sopenharmony_ci // the loop runs long enough for the test to complete. 561cb0ef41Sopenharmony_ci await pause(); 571cb0ef41Sopenharmony_ci await pause(); 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci})().then(common.mustCall()); 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci{ 621cb0ef41Sopenharmony_ci const signal = transferableAbortSignal(AbortSignal.abort('boom')); 631cb0ef41Sopenharmony_ci ok(signal.aborted); 641cb0ef41Sopenharmony_ci strictEqual(signal.reason, 'boom'); 651cb0ef41Sopenharmony_ci const mc = new MessageChannel(); 661cb0ef41Sopenharmony_ci mc.port1.onmessage = common.mustCall(({ data }) => { 671cb0ef41Sopenharmony_ci ok(data instanceof AbortSignal); 681cb0ef41Sopenharmony_ci ok(data.aborted); 691cb0ef41Sopenharmony_ci strictEqual(data.reason, 'boom'); 701cb0ef41Sopenharmony_ci mc.port1.close(); 711cb0ef41Sopenharmony_ci }); 721cb0ef41Sopenharmony_ci mc.port2.postMessage(signal, [signal]); 731cb0ef41Sopenharmony_ci} 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci{ 761cb0ef41Sopenharmony_ci // The cloned AbortSignal does not keep the event loop open 771cb0ef41Sopenharmony_ci // waiting for the abort to be triggered. 781cb0ef41Sopenharmony_ci const ac = transferableAbortController(); 791cb0ef41Sopenharmony_ci const mc = new MessageChannel(); 801cb0ef41Sopenharmony_ci mc.port1.onmessage = common.mustCall(); 811cb0ef41Sopenharmony_ci mc.port2.postMessage(ac.signal, [ac.signal]); 821cb0ef41Sopenharmony_ci mc.port2.close(); 831cb0ef41Sopenharmony_ci} 84