From 5e6967359be66e7b0c9d9abd152a1636a417872f Mon Sep 17 00:00:00 2001 From: atlowChemi Date: Thu, 14 Mar 2024 10:52:31 +0200 Subject: [PATCH] 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 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Antoine du Hamel Reviewed-By: Luigi Pinca --- lib/events.js | 30 +------------- lib/internal/events/abort_listener.js | 54 +++++++++++++++++++++++++ test/parallel/test-bootstrap-modules.js | 1 + 3 files changed, 56 insertions(+), 29 deletions(-) create mode 100644 lib/internal/events/abort_listener.js diff --git a/lib/events.js b/lib/events.js index 9b97517f3c72ab..837b30f311d4a7 100644 --- a/lib/events.js +++ b/lib/events.js @@ -83,6 +83,7 @@ const { validateNumber, validateString, } = require('internal/validators'); +const { addAbortListener } = require('internal/events/abort_listener'); const kCapture = Symbol('kCapture'); const kErrorMonitor = Symbol('events.errorMonitor'); @@ -1219,32 +1220,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?.(); - }, - }; -} diff --git a/lib/internal/events/abort_listener.js b/lib/internal/events/abort_listener.js new file mode 100644 index 00000000000000..033cbf7b250fe0 --- /dev/null +++ b/lib/internal/events/abort_listener.js @@ -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, +}; diff --git a/test/parallel/test-bootstrap-modules.js b/test/parallel/test-bootstrap-modules.js index 5c4def64cd0aa0..7b9a05711e170b 100644 --- a/test/parallel/test-bootstrap-modules.js +++ b/test/parallel/test-bootstrap-modules.js @@ -98,6 +98,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([