From 94b9e6d9e8c9d095ac5bb13075265eab7b57b531 Mon Sep 17 00:00:00 2001 From: JrMasterModelBuilder Date: Mon, 2 Oct 2023 23:57:38 -0400 Subject: [PATCH] Added syncronous cleanup method --- src/archive.ts | 9 +++++++++ src/archive/hdi.ts | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/archive.ts b/src/archive.ts index 1cec0af..f4e3b0e 100644 --- a/src/archive.ts +++ b/src/archive.ts @@ -861,6 +861,15 @@ export abstract class Archive { afters.delete(resolve(path)); } + /** + * Syncronously cleanup temporary resources. + * Can be called on shutdown/abort/signals to free resources. + * Not applicable to most archive formats. + */ + public cleanup() { + // Do nothing. + } + /** * Read archive. * If the itter callback returns false, reading ends. diff --git a/src/archive/hdi.ts b/src/archive/hdi.ts index 18664d1..ee13cb7 100644 --- a/src/archive/hdi.ts +++ b/src/archive/hdi.ts @@ -3,11 +3,12 @@ import {Stats, createReadStream} from 'node:fs'; import {basename, join as pathJoin} from 'node:path'; -import {Mounter} from '@shockpkg/hdi-mac'; +import {IMounterAttachInfo, Mounter} from '@shockpkg/hdi-mac'; import {Archive, Entry, IEntryInfo} from '../archive'; import {PathType} from '../types'; import { + IFsWalkSignal, fsLstatExists, fsReadlinkRaw, fsWalk, @@ -196,6 +197,11 @@ export class ArchiveHdi extends Archive { */ public nobrowse = false; + protected _active = new Set<{ + info: IMounterAttachInfo; + signal: IFsWalkSignal; + }>(); + /** * ArchiveHdi constructor. * @@ -205,6 +211,23 @@ export class ArchiveHdi extends Archive { super(path); } + /** + * Call this to eject actively open disk images on shutdown. + * + * @inheritdoc + */ + public cleanup() { + const active = this._active; + for (const a of this._active) { + a.signal.abort = true; + // eslint-disable-next-line no-sync + a.info.ejectSync({ + force: true + }); + active.delete(a); + } + } + /** * Read archive. * If the itter callback returns false, reading ends. @@ -323,6 +346,10 @@ export class ArchiveHdi extends Archive { readonly: true }); + const signal = {}; + const active = {info, signal}; + this._active.add(active); + // Eject device when done. try { for (const device of info.devices) { @@ -340,11 +367,13 @@ export class ArchiveHdi extends Archive { const pathRaw = pathJoin(volumeName, pathRel); return each(pathFull, pathRaw, stat); }, - walkOpts + walkOpts, + signal ); } } finally { await info.eject(); + this._active.delete(active); } } }