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