events: extract addAbortListener for safe internal use

Refs: https://github.com/nodejs/node/pull/48596
PR-URL: https://github.com/nodejs/node/pull/52081
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
atlowChemi authored and Node.js GitHub Bot committed 2024-03-16 09:08:55 +00:00
1 parent ba06c5c509
commit e263946c2e
3 files changed
+56 -29

No files matched your search

+1 -29
View File
@@ -84,6 +84,7 @@ const {
validateObject,
validateString,
} = require('internal/validators');
const { addAbortListener } = require('internal/events/abort_listener');
const kCapture = Symbol('kCapture');
const kErrorMonitor = Symbol('events.errorMonitor');
@@ -1222,32 +1223,3 @@ function listenersController() {
},
};
}
let queueMicrotask;
function addAbortListener(signal, listener) {
if (signal === undefined) {
throw new ERR_INVALID_ARG_TYPE('signal', 'AbortSignal', signal);
}
validateAbortSignal(signal, 'signal');
validateFunction(listener, 'listener');
let removeEventListener;
if (signal.aborted) {
queueMicrotask ??= require('internal/process/task_queues').queueMicrotask;
queueMicrotask(() => listener());
} else {
kResistStopPropagation ??= require('internal/event_target').kResistStopPropagation;
// TODO(atlowChemi) add { subscription: true } and return directly
signal.addEventListener('abort', listener, { __proto__: null, once: true, [kResistStopPropagation]: true });
removeEventListener = () => {
signal.removeEventListener('abort', listener);
};
}
return {
__proto__: null,
[SymbolDispose]() {
removeEventListener?.();
},
};
}
+54
View File
@@ -0,0 +1,54 @@
'use strict';
const {
SymbolDispose,
} = primordials;
const {
validateAbortSignal,
validateFunction,
} = require('internal/validators');
const {
codes: {
ERR_INVALID_ARG_TYPE,
},
} = require('internal/errors');
let queueMicrotask;
let kResistStopPropagation;
/**
* @param {AbortSignal} signal
* @param {EventListener} listener
* @returns {Disposable}
*/
function addAbortListener(signal, listener) {
if (signal === undefined) {
throw new ERR_INVALID_ARG_TYPE('signal', 'AbortSignal', signal);
}
validateAbortSignal(signal, 'signal');
validateFunction(listener, 'listener');
let removeEventListener;
if (signal.aborted) {
queueMicrotask ??= require('internal/process/task_queues').queueMicrotask;
queueMicrotask(() => listener());
} else {
kResistStopPropagation ??= require('internal/event_target').kResistStopPropagation;
// TODO(atlowChemi) add { subscription: true } and return directly
signal.addEventListener('abort', listener, { __proto__: null, once: true, [kResistStopPropagation]: true });
removeEventListener = () => {
signal.removeEventListener('abort', listener);
};
}
return {
__proto__: null,
[SymbolDispose]() {
removeEventListener?.();
},
};
}
module.exports = {
__proto__: null,
addAbortListener,
};
+1
View File
@@ -99,6 +99,7 @@ expected.beforePreExec = new Set([
'Internal Binding module_wrap',
'NativeModule internal/modules/cjs/loader',
'Internal Binding wasm_web_api',
'NativeModule internal/events/abort_listener',
]);
expected.atRunTime = new Set([