// This should always happen, however GC is // indeterministic so it might not happen. /* istanbul ignore else */ if (obj !== undefined) { fn(obj, event); } } refs[event] = []; } function clear(ref) { for (const event of ['exit', 'beforeExit']) { const index = ArrayPrototypeIndexOf(refs[event], ref); ArrayPrototypeSplice(refs[event], index, index + 1); uninstall(event); } } function _register(event, obj, fn) { install(event); const ref = new SafeWeakRef(obj); ref.fn = fn; registry ||= new SafeFinalizationRegistry(clear); registry.register(obj, ref); ArrayPrototypePush(refs[event], ref); } /** * Execute the given function when the process exits, * and clean things up when the object is gc. * @param {any} obj * @param {Function} fn */ function register(obj, fn) { emitExperimentalWarning('process.finalization.register'); validateObject(obj, 'obj', kValidateObjectAllowFunction); _register('exit', obj, fn); } /** * Execute the given function before the process exits, * and clean things up when the object is gc. * @param {any} obj * @param {Function} fn */ function registerBeforeExit(obj, fn) { emitExperimentalWarning('process.finalization.registerBeforeExit'); validateObject(obj, 'obj', kValidateObjectAllowFunction); _register('beforeExit', obj, fn); } /** * Unregister the given object from the onExit or onBeforeExit event. * @param {object} obj */ function unregister(obj) { emitExperimentalWarning('process.finalization.unregister'); if (!registry) { return; } registry.unregister(obj); for (const event of ['exit', 'beforeExit']) { refs[event] = ArrayPrototypeFilter(refs[event], (ref) => { const _obj = ref.deref(); return _obj && _obj !== obj; }); uninstall(event); } } return { register, registerBeforeExit, unregister, }; } module.exports = { createFinalization, };