From 00cb04ff41ccafe54fc9581d49573b01a6985ee5 Mon Sep 17 00:00:00 2001 From: Viorel Munteanu Date: Mon, 24 Aug 2026 13:17:40 +0000 Subject: [PATCH] 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 Claude-Session: https://claude.ai/code/session_01Gv3s5jckJKzh6JkMoi2Akz --- CLAUDE.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 98985ce..56c8b4d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 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 directory is `buildDir/` (already configured).