Docs/Files & system

Signals

React to Ctrl+C and other OS signals.

On this page

valk.signal lets a program react to Ctrl+C, kill and the other process signals. Your code never runs inside the signal handler itself, so it may do anything a normal function does.

Stop cleanly on Ctrl+C#

cancel_on_shutdown cancels a sync.CancelToken when SIGINT or SIGTERM (and SIGHUP where it exists) arrives. Wait on the token, then shut down:

Valk
use valk.signal
use valk.sync
use valk.http

fn handle(req: http.Request) http.Response {
    return http.Response.text("Hello")
}

fn main() {
    let stop: sync.CancelToken = sync.CancelToken.new() ! return
    signal.cancel_on_shutdown(stop) ! return

    let server = http.Server.new("127.0.0.1", 8080, handle)
    let running = co server.start()
    stop.wait()
    println("Shutting down")
    server.shutdown()
    await running ! return
}

cancel_on(sig, token) does the same for one signal. An HTTP server can also do this by itself: see graceful shutdown.

The signals#

signal.Signal OS signal Windows
interrupt SIGINT (Ctrl+C) yes
terminate SIGTERM yes
hangup SIGHUP no
quit SIGQUIT no
user1, user2 SIGUSR1, SIGUSR2 no

Functions throw unsupported for a signal the platform does not have.

Run code or wait for a signal#

Valk
use valk.signal

fn main() {
    signal.on(.user1, fn() { println("got SIGUSR1") }) ! return
    let waiting = co signal.wait(.user1, 2000)
    signal.raise(.user1) ! return
    let arrived = await waiting ! return
    println(arrived) // true
}
Function Does
on(sig, callback) Runs callback each time the signal arrives, on a thread of its own
wait(sig, timeout_ms) Pauses the coroutine until the signal arrives; false on timeout (0 waits forever)
ignore(sig) Makes the process ignore the signal
restore(sig) Restores the default action and drops what was registered
raise(sig) Sends the signal to this process
number(sig) The OS signal number

A callback from on runs on another thread, so it is an atomic fn: it may capture numbers and atomic values (see Threads).

Signal a child process#

A started process takes the same enum: child.signal(.terminate).