From d8b010c79c53f36f7bb9dfca287a10d6c802279c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 27 Mar 2024 21:14:33 +0100 Subject: [PATCH] Support cancellation of installation process (#770) We wrap the installation with a withTaskCancellationHandler, which ensures that the SIGINT signal handling code in main() will trigger a cancellation of the installer. As the VZMacOSInstaller must be both created and interacted with on the VM's queue, which in our case is the main queue, we need to move the logic to a separate function tagged with @MainActor. This makes sense either way, as it cleans up the code a bit. --- Sources/tart/VM.swift | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Sources/tart/VM.swift b/Sources/tart/VM.swift index a129d92..6345588 100644 --- a/Sources/tart/VM.swift +++ b/Sources/tart/VM.swift @@ -191,18 +191,24 @@ class VM: NSObject, VZVirtualMachineDelegate, ObservableObject { virtualMachine.delegate = self // Run automated installation - try await withCheckedThrowingContinuation { (continuation: CheckedContinuation) in - DispatchQueue.main.async { [ipswURL] in - let installer = VZMacOSInstaller(virtualMachine: self.virtualMachine, restoringFromImageAt: ipswURL) + try await install(ipswURL) + } - defaultLogger.appendNewLine("Installing OS...") - ProgressObserver(installer.progress).log(defaultLogger) + @MainActor + private func install(_ url: URL) async throws { + let installer = VZMacOSInstaller(virtualMachine: self.virtualMachine, restoringFromImageAt: url) + defaultLogger.appendNewLine("Installing OS...") + ProgressObserver(installer.progress).log(defaultLogger) + try await withTaskCancellationHandler(operation: { + try await withCheckedThrowingContinuation { continuation in installer.install { result in continuation.resume(with: result) } } - } + }, onCancel: { + installer.progress.cancel() + }) } #endif