1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/// Resolves once on Ctrl+C, (Unix only) SIGTERM, or (Windows only)
/// `CTRL_BREAK_EVENT` - the ways a running app is normally asked to stop.
///
/// The Windows case needs its own explanation, confirmed empirically (not
/// from documentation alone) via a throwaway spike: `tokio::signal::
/// ctrl_c()` on Windows only ever resolves on a real `CTRL_C_EVENT`. An
/// *external* controlling process (a supervisor, this crate's own future
/// restart-handoff orchestration, or a test harness) cannot reliably send
/// `CTRL_C_EVENT` to a specific target process - `GenerateConsoleCtrlEvent`
/// only accepts `dwProcessGroupId = 0` for `CTRL_C_EVENT`, which broadcasts
/// to *every* process sharing the sender's own console (including the
/// sender itself), not a single chosen target. `CTRL_BREAK_EVENT` is the
/// one console-control event that *can* target one specific process group
/// (the child must be spawned with `CREATE_NEW_PROCESS_GROUP` for this),
/// which is why an external, deliberate "ask this one process to stop" is
/// only reliably deliverable as a break event on this platform - but
/// `ctrl_c()` alone does not listen for it: a `CTRL_BREAK_EVENT` with no
/// application handler for it falls through to the OS's own default
/// handler, which just terminates the process outright
/// (`STATUS_CONTROL_C_EXIT`), skipping graceful shutdown entirely. Proven
/// by first reproducing that exact failure, then fixing it by explicitly
/// also listening on `tokio::signal::windows::ctrl_break()` here - see
/// `docs/GOTCHAS.md`.
pub async