Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions lib/internal/abort_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,12 @@ class AbortSignal extends EventTarget {
for (let i = 0; i < signalsArray.length; i++) {
const signal = signalsArray[i];

refreshCompositeSignal(signal);
if (signal[kAborted]) {
abortSignal(resultSignal, signal[kReason]);
return resultSignal;
}

// Check if this is a timeout signal
if (signal[kTimeout]) {
hasTimeoutSignals = true;
Expand All @@ -345,12 +351,6 @@ class AbortSignal extends EventTarget {
gcPersistentSignals.add(signal);
}

refreshCompositeSignal(signal);
if (signal[kAborted]) {
abortSignal(resultSignal, signal[kReason]);
return resultSignal;
}

if (!signal[kComposite]) {
const signalWeakRef = new SafeWeakRef(signal);
resultSignal[kSourceSignals].add(signalWeakRef);
Expand Down
12 changes: 12 additions & 0 deletions test/parallel/test-abort-controller-any-timeout.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
'use strict';

const common = require('../common');
const { gcUntil } = require('../common/gc');
const assert = require('assert');
const { once } = require('node:events');
const { describe, it } = require('node:test');
Expand Down Expand Up @@ -39,4 +40,15 @@ describe('AbortSignal.any() with timeout signals', () => {
clearTimeout(timeout);
}
});

it('should not retain a timeout signal that has already fired', async () => {
let signal = AbortSignal.timeout(1);
const ref = new WeakRef(signal);
await once(signal, 'abort');

AbortSignal.any([signal]);
signal = null;

await gcUntil('fired timeout signal is collected', () => ref.deref() === undefined);
});
});
Loading