Skip to content

Commit

Permalink
fix(ext/web): propagate aborted state to dependent signals before fir…
Browse files Browse the repository at this point in the history
…ing events

Ref whatwg/dom#1295

Fixes denoland#25118
  • Loading branch information
littledivy committed Aug 21, 2024
1 parent 5168700 commit 18b618a
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 7 deletions.
34 changes: 27 additions & 7 deletions ext/web/03_abort_signal.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class WeakRefSet {
}

const add = Symbol("[[add]]");
const setAbortReason = Symbol("[[setAbortReason]]");
const signalAbort = Symbol("[[signalAbort]]");
const remove = Symbol("[[remove]]");
const abortReason = Symbol("[[abortReason]]");
Expand Down Expand Up @@ -148,7 +149,22 @@ class AbortSignal extends EventTarget {
if (this.aborted) {
return;
}
this[abortReason] = reason;

this[setAbortReason](reason);

const dependentSignalsToAbort = [];
if (this[dependentSignals] !== null) {
const dependentSignalArray = this[dependentSignals].toArray();
for (let i = 0; i < dependentSignalArray.length; ++i) {
const dependentSignal = dependentSignalArray[i];

if (!dependentSignal.aborted) {
dependentSignal[setAbortReason](reason);
dependentSignalsToAbort.push(dependentSignal);
}
}
}

const algos = this[abortAlgos];
this[abortAlgos] = null;

Expand All @@ -163,15 +179,19 @@ class AbortSignal extends EventTarget {
}
}

if (this[dependentSignals] !== null) {
const dependentSignalArray = this[dependentSignals].toArray();
for (let i = 0; i < dependentSignalArray.length; ++i) {
const dependentSignal = dependentSignalArray[i];
dependentSignal[signalAbort](reason);
}
for (let i = 0; i < dependentSignalsToAbort.length; ++i) {
const dependentSignal = dependentSignalsToAbort[i];
dependentSignal[signalAbort](reason);
}
}

[setAbortReason](reason) {
if (this.aborted) {
return;
}
this[abortReason] = reason;
}

[remove](algorithm) {
this[abortAlgos] && SetPrototypeDelete(this[abortAlgos], algorithm);
}
Expand Down
19 changes: 19 additions & 0 deletions tests/unit/abort_controller_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,22 @@ Deno.test(function abortReason() {
assertEquals(signal.aborted, true);
assertEquals(signal.reason, "hey!");
});

Deno.test(function dependentSignalsAborted() {
const controller = new AbortController();
const signal1 = AbortSignal.any([controller.signal]);
const signal2 = AbortSignal.any([signal1]);
let eventFired = false;

controller.signal.addEventListener("abort", () => {
const signal3 = AbortSignal.any([signal2]);
assert(controller.signal.aborted);
assert(signal1.aborted);
assert(signal2.aborted);
assert(signal3.aborted);
eventFired = true;
});

controller.abort();
assert(eventFired, "event fired");
});

0 comments on commit 18b618a

Please sign in to comment.