code wiki / _hdl_build / nx_gallery_keepalive.nx
nx_gallery_keepalive.nx source
↩ module page · 46 lines · 2305 B
1// nx_gallery_keepalive.nx -- SOVEREIGN Nishi supervisor for the gallery daemon.
2// NO PowerShell, NO bash logic: the keepalive LOGIC is pure NishiLang (compiled by nx_cc_sovereign).
3// It (a) holds the WSL VM alive -- a perpetually-running Nishi process keeps the VM from idle-shutting-
4// down (the root cause of the daemon dying), and (b) supervises the gallery daemon: fork -> execve the
5// daemon -> wait4; if the daemon ever exits/crashes, brief poll-sleep then relaunch.
6// Last-mile launch only (incumbent used as launcher, never substrate):
7// wsl.exe -e bash -lc 'cd <nxc2> && setsid ./runtime/_hdl_build/nx_gallery_keepalive.elf >log 2>&1 &'
8// license_tier: ORIGINAL
9import "nx_syscalls.nx"
10const GALX_MAGIC_2000: i64 = 2000
11
12const GALX_DAEMON: *u8 = "/mnt/c/Users/elder/nishi-core/nxc2/runtime/_hdl_build/nx_gallery_serve.elf" as *u8
13
14func main() -> i64 {
15 // SELF-MANAGE: daemonize (fork + setsid + parent-exit) so a watchdog-bounded reviver
16 // (nx_boot_revive RUNS this supervisor under a SIGKILL deadline) returns immediately while
17 // the supervise loop survives DETACHED in its own session -- the gallery now auto-revives on
18 // every boot via the root nx-boot-revive.service (D row in triage_expected.conf), zero
19 // sessions/operator needed. The new session also detaches us from the launcher's process
20 // group so its timeout-SIGKILL cannot reap the live supervisor.
21 let dpid: i64 = sys_fork()
22 if dpid > 0 { sys_exit(0); return 0 }
23 nx_setsid()
24 // argv = [daemon_path, NULL] ; envp = [NULL]
25 let argv: *i64 = sys_mmap(16) as *i64
26 argv[0] = GALX_DAEMON as i64
27 argv[1] = 0
28 let envp: *i64 = sys_mmap(8) as *i64
29 envp[0] = 0
30 let st: *i64 = sys_mmap(8) as *i64
31 while 1 == 1 {
32 let pid: i64 = sys_fork()
33 if pid == 0 {
34 // child: become the gallery daemon (cwd inherited = nxc2, so its relative reads work)
35 sys_execve(GALX_DAEMON, argv, envp)
36 sys_exit(127)
37 }
38 if pid > 0 {
39 // parent: block until the daemon exits, then loop to relaunch it
40 sys_wait4(pid, st, 0)
41 }
42 // brief guard so a crash-on-bind can't 100%-spin (poll(NULL,0,timeout) = sovereign sleep)
43 sys_poll(0 as *i64, 0, GALX_MAGIC_2000)
44 }
45 return 0
46}