Graceful stop on SIGTERM
wired_server_run installs a SIGTERM handler before serving (RFC 9114
5.2): on receipt, new connections stop being accepted, GOAWAY goes out once
to every still-live connection, and the process exits once every connection
has drained or a bounded grace period elapses. wired_srvworkers_run (the
--workers fan-out behind wired_srvdriver_run) layers a supervisor on
top: it forwards the one SIGTERM to every live worker and stops respawning
crashed ones, so the whole process group still winds down together.
This page runs one worker (--workers 1), answers a request, then is sent
SIGTERM.
Code
#define WIRED_MAIN#include "wired.h"
static int on_request( void* ctx, const wired_h3reqdrive_req* req, u64 offset, wired_obuf* body_out, const char** content_type, int* more, u64* total_size) { (void)ctx; (void)req; (void)offset; (void)more; (void)total_size; *content_type = "text/plain"; wired_obuf_printf(body_out, "ok"); return 1;}
int wired_main(int argc, char** argv) { /* The same fixed demo identity as the HTTP/3 hello page. */ static wired_srvboot_demo_keys keys; wired_srvboot_id id; wired_srvboot_demo(&id, &keys, 0x50, "guide-h3");
/* --port, --workers, --cores, --ifindex, ... pick and configure a driver. */ wired_srvdriver_opt opt = {0}; if (!wired_srvdriver_parse(argc, argv, &opt)) { wired_log_str("bad flags\n"); return 2; } wired_srvrun_handler h = {.cb = on_request}; wired_srvrun_obs obs = {0}; return wired_srvdriver_run(&id, h, obs, &opt) < 0 ? 1 : 0;}Output
$ ./ops-shutdown --port 4433 --workers 1conn closed by peer (CONNECTION_CLOSE)$ probe h3get 127.0.0.1:4433 /GET / status=200 content-type=text/plain body="ok"How it works
Section titled “How it works”wired_srvdriver_parse/wired_srvdriver_runpick the driver from argv the same wayops/handshake-knobsdoes;--workers 1selectswired_srvworkers_runwith exactly one forked child.- The supervisor’s own SIGTERM handler only sets a flag (async-signal-safe); the reap loop forwards SIGTERM to every live worker’s pid exactly once and stops re-forking a replacement for a worker that exits — a crash during shutdown is not respawned.
- Each worker’s own copy of
wired_server_runruns unmodified: it is theSIGTERMthe supervisor forwards that drives its own graceful-shutdown path (no new connections, GOAWAY, drain-then-exit) described above. --workersbeyond 1 is not exercised here: more than one worker shares the port throughSO_REUSEPORT’s kernel-side hash alone, with no per-worker steering, whichwired_srvworkers_run’s own doc flags as an intermittent-handshake risk under this fork model.--workers 1sidesteps that while still exercising the real supervisor/forward/reap path.