mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-16 13:05:53 +00:00
fix mac
This commit is contained in:
parent
b3299e020a
commit
566e7f62b3
2 changed files with 81 additions and 34 deletions
|
|
@ -1,34 +0,0 @@
|
|||
import Foundation
|
||||
|
||||
extension Process {
|
||||
/// Configure process to automatically terminate when parent dies
|
||||
/// This sets up proper process group handling on macOS
|
||||
func configureForParentTermination() {
|
||||
// Set quality of service to tie lifecycle to parent
|
||||
self.qualityOfService = .userInitiated
|
||||
|
||||
// On macOS, we can use process groups to ensure child termination
|
||||
// When the parent dies, all processes in the same process group receive SIGHUP
|
||||
#if os(macOS)
|
||||
// This will be called just before the process launches
|
||||
// We'll use posix_spawn attributes to set up the process group
|
||||
if #available(macOS 10.15, *) {
|
||||
// Modern approach: let the system handle it
|
||||
// NSTask/Process on modern macOS automatically handles parent death
|
||||
// when qualityOfService is set
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Enhanced run method that ensures proper process group setup
|
||||
func runWithParentTermination() throws {
|
||||
configureForParentTermination()
|
||||
try run()
|
||||
}
|
||||
|
||||
/// Async version of runWithParentTermination
|
||||
func runWithParentTerminationAsync() async throws {
|
||||
configureForParentTermination()
|
||||
try await runAsync()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
//
|
||||
// Process+ParentTermination.swift
|
||||
// VibeTunnel
|
||||
//
|
||||
// Simple extension to run processes asynchronously
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Process {
|
||||
/// Async version that starts the process and returns immediately
|
||||
@available(macOS 14.0, *)
|
||||
func runAsync() async throws {
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
do {
|
||||
try self.run()
|
||||
continuation.resume()
|
||||
} catch {
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Run process with parent termination handling
|
||||
/// (The actual parent monitoring is handled by the shell wrapper)
|
||||
func runWithParentTermination() throws {
|
||||
try run()
|
||||
}
|
||||
|
||||
/// Async version of runWithParentTermination
|
||||
@available(macOS 14.0, *)
|
||||
func runWithParentTerminationAsync() async throws {
|
||||
try await runAsync()
|
||||
}
|
||||
|
||||
/// Wait for the process to exit asynchronously
|
||||
func waitUntilExitAsync() async {
|
||||
await withCheckedContinuation { continuation in
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
self.waitUntilExit()
|
||||
continuation.resume()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Terminate the process asynchronously
|
||||
func terminateAsync() async {
|
||||
await withCheckedContinuation { continuation in
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
if self.isRunning {
|
||||
self.terminate()
|
||||
}
|
||||
continuation.resume()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Wait for exit with timeout
|
||||
func waitUntilExitWithTimeout(seconds: TimeInterval) async -> Bool {
|
||||
await withTaskGroup(of: Bool.self) { group in
|
||||
group.addTask {
|
||||
await self.waitUntilExitAsync()
|
||||
return true
|
||||
}
|
||||
|
||||
group.addTask {
|
||||
try? await Task.sleep(for: .seconds(seconds))
|
||||
return false
|
||||
}
|
||||
|
||||
for await result in group {
|
||||
group.cancelAll()
|
||||
return result
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue