Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions Sources/LiveAudioServer/LiveAudioServerApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ func printUsage() {
stay live.
--no-fifo-reopen Disable the FIFO re-open behaviour above; the
reader will silence-fill after EOF instead.
--exit-with-parent Exit if the parent process dies (even on a
crash). Useful when launched as a helper by a
host app that needs this server reaped instead
of orphaned holding its HTTP port.
--silence-dither Inject inaudible TPDF dither (±1 LSB) once a
run of digitally-silent samples crosses
--silence-dither-ms. Prevents downstream
Expand Down Expand Up @@ -219,6 +223,25 @@ struct LiveAudioServerApp {
sigTerm.resume()
_ = sigInt; _ = sigTerm

// Parent-death watchdog (--exit-with-parent). Polls getppid(); when the
// launching app dies (quit or crash) this process is reparented to
// launchd (pid 1), so getppid() changes — at which point we shut down
// gracefully, freeing the HTTP port instead of orphaning it.
var parentWatchdog: DispatchSourceTimer?
if config.exitWithParent {
let originalParent = getppid()
let timer = DispatchSource.makeTimerSource(queue: .global())
timer.schedule(deadline: .now() + 0.5, repeating: 0.5)
timer.setEventHandler {
if getppid() != originalParent {
runGracefulShutdown("Parent process exit")
}
}
timer.resume()
parentWatchdog = timer
}
_ = parentWatchdog

RunLoop.main.run()
}
}
2 changes: 2 additions & 0 deletions Sources/LiveAudioServerCore/CLIParse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ public func parseCLI(_ args: [String]) -> CLIParseResult {
config.httpAuthRealm = r
case "--keep-alive":
config.keepAliveOnInputEnd = true
case "--exit-with-parent":
config.exitWithParent = true
case "--no-fifo-reopen":
config.reopenStdinFIFO = false
case "--silence-dither":
Expand Down
5 changes: 5 additions & 0 deletions Sources/LiveAudioServerCore/Config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ public struct ServerConfig {
public var aacBitrate: Int = 128_000 // bps (AudioToolbox uses bps)
public var verbose: Bool = false
public var stdinChunkFrames: Int = 4096 // PCM frames read per stdin iteration
/// When set, the CLI exits if its parent process dies (even on a crash where
/// the parent can't run cleanup). Lets a host app guarantee this helper is
/// reaped rather than orphaned holding its HTTP port. CLI-only; see
/// `LiveAudioServerApp`.
public var exitWithParent: Bool = false
public var keepAliveOnInputEnd: Bool = false
/// When the input stream is a FIFO/named pipe and `keepAliveOnInputEnd` is
/// on, re-`open()` the same path on EOF so a new producer can attach.
Expand Down
Loading