Module signal

Module signal 

Source
Expand description

Signal handling API for Seq

Provides Unix signal handling with a safe, flag-based approach:

  • Signals are trapped and set atomic flags (no code runs in signal context)
  • User code polls for signals at safe points
  • Fits Seq’s explicit, predictable style

§Example

signal.SIGINT signal.trap
signal.SIGTERM signal.trap

: main-loop ( -- )
  signal.SIGINT signal.received? if
    "Shutting down..." io.write-line
    return
  then
  do-work
  main-loop
;

§Safety

Signal handlers execute in an interrupt context with severe restrictions. This module uses only async-signal-safe operations (atomic flag setting). All Seq code execution happens outside the signal handler, when the user explicitly checks for received signals.

§Thread Safety and Concurrent Access

This module is designed to be safe for concurrent use from multiple strands:

  • Handler installation (signal.trap, signal.default, signal.ignore): Protected by a mutex to ensure only one strand modifies handlers at a time. Concurrent calls will serialize safely.

  • Flag operations (signal.received?, signal.pending?, signal.clear): Use lock-free atomic operations with appropriate memory ordering:

    • signal.received?: Atomic swap with Acquire ordering (read-modify-write)
    • signal.pending?: Atomic load with Acquire ordering (read-only)
    • signal.clear: Atomic store with Release ordering (write-only)

    Multiple strands can safely check the same signal. However, signal.received? clears the flag atomically, so if two strands both call it, only one will observe true. Use signal.pending? if you need non-destructive reads.

  • Signal handler: Executes outside the strand context (in OS interrupt context) and only performs a single atomic store. This is async-signal-safe.

This module uses sigaction() instead of the deprecated signal() function for well-defined behavior in multithreaded environments.

§Platform Support

  • Unix: Full signal support using sigaction()
  • Windows: Stub implementations (signals not supported, all operations no-op)

Functions§

patch_seq_signal_clear
Clear the flag for a signal without checking it
patch_seq_signal_default
Restore the default handler for a signal
patch_seq_signal_ignore
Ignore a signal entirely
patch_seq_signal_pending
Check if a signal is pending without clearing the flag
patch_seq_signal_received
Check if a signal was received and clear the flag
patch_seq_signal_sigalrm
Get SIGALRM constant (alarm clock)
patch_seq_signal_sigchld
Get SIGCHLD constant (child status change)
patch_seq_signal_sigcont
Get SIGCONT constant (continue)
patch_seq_signal_sighup
Get SIGHUP constant (hangup)
patch_seq_signal_sigint
Get SIGINT constant (Ctrl+C interrupt)
patch_seq_signal_sigpipe
Get SIGPIPE constant (broken pipe)
patch_seq_signal_sigterm
Get SIGTERM constant (termination request)
patch_seq_signal_sigusr1
Get SIGUSR1 constant (user signal 1)
patch_seq_signal_sigusr2
Get SIGUSR2 constant (user signal 2)
patch_seq_signal_trap
Trap a signal: install handler that sets flag instead of default behavior