Document global-state audit and fork-per-container decision

Ahead of docker-compose multi-container support, audited the three pieces
of mutable global state (g_mount_program, g_foreground_child_pid,
g_report_fd/g_log_path) for concurrency safety. Decided each container's
session will run in its own forked OS process, the same model
-D/--daemonize already uses, rather than one process managing multiple
containers without forking. Under that model none of the globals need to
change, since "one OS process" already equals "one running container" --
recorded as a load-bearing constraint for the compose orchestrator.

No code changes; documentation only.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gv3s5jckJKzh6JkMoi2Akz
This commit is contained in:
2026-08-24 13:17:40 +00:00
parent 61f542080d
commit 00cb04ff41
+21
View File
@@ -462,6 +462,27 @@ failed: Invalid argument") since the caller is already in that same user namespa
`-n/--no-nsenter` forces it off manually for any other situation where the mount turns `-n/--no-nsenter` forces it off manually for any other situation where the mount turns
out to already be directly visible. out to already be directly visible.
**Mutable global state and multi-container support:** an audit ahead of planned
docker-compose support (running multiple containers at once) found exactly three
pieces of mutable global/file-scope state in `src/`: `g_mount_program`
(`containers_storage.{h,cpp}`, the resolved `fuse-overlayfs` path — genuinely
process-wide, invariant across containers), `g_foreground_child_pid`
(`process.cpp`, plus `run_process_foreground()`'s process-wide `SIGINT`/`SIGTERM`
handler installation — tracks one foreground child at a time), and
`g_report_fd`/`g_log_path` (`daemonize.cpp`, one in-flight `-D/--daemonize`
handshake's report-pipe fd and log path). **Decision, confirmed by the user:**
multi-container/compose support will run each container's session in its own
forked OS process — the same model `-D/--daemonize` already uses — rather than
one process managing multiple containers concurrently without forking. Under
that model, "one OS process" and "one running container" stay the same thing
they already are today, so **none of these globals need to become per-container
state** — each forked child only ever tracks/signals one foreground child and
handles one daemonize handshake, exactly as today. This is a load-bearing
constraint for however the compose orchestrator ends up implemented: it must
fork (not thread, not run an in-process event loop over N containers) one child
per service, each child reusing `run_container()`'s existing single-container
code path unchanged.
## Build & test commands ## Build & test commands
Build directory is `buildDir/` (already configured). Build directory is `buildDir/` (already configured).