From 35e5d32901c9a35700d3d8b046971dafc9bed5fe Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Sat, 13 Jun 2026 23:23:15 +0900 Subject: kernel: generalize the inotify watcher into a Host::watch_file service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hot-reload watcher was substrate-internal; expose it as a typed RAII primitive any extension can use (config hot-reload is the first consumer), per "the kernel owns the event/service bus; extensions never hold raw event-loop glue". - New public watch.hpp: `class FileWatch` (move-only RAII; ~/reset() stop the watch) + `Host::watch_file(path, on_change) -> FileWatch`. on_change fires on the event-loop thread, COALESCED (one save = one call), EDITOR-SAFE (dir-watch the basename across temp+rename), fires on CREATE of a not-yet-existing file, and is ERROR-ISOLATED to the calling extension (carries its id; a throw disables only that extension). UNGATED — works without UNBOX_DEV. - New src/file_watcher.{hpp,cpp}: ONE session-wide inotify instance on the wl_event_loop multiplexing all watched paths. The substrate's UI-asset hot-reload was refactored onto it (no second inotify); only the substrate's *decision* to watch UI assets stays UNBOX_DEV-gated. Created lazily on first watch; torn down leak-clean before the loop dies. host.hpp/kernel.md documented. kernel 58 cases/254 assertions green on build + build-asan (incl. the inotify path), no new suppressions. Edits confined to packages/kernel/. --- packages/kernel/kernel.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'packages/kernel/kernel.md') diff --git a/packages/kernel/kernel.md b/packages/kernel/kernel.md index 0bb8868..32f2a0d 100644 --- a/packages/kernel/kernel.md +++ b/packages/kernel/kernel.md @@ -138,6 +138,18 @@ spike retired into this — same GL bridge mechanics, now per-surface + real): - **`Server::ui_*` probes are test instrumentation only** (frame_count, orientation, fence_sync_active, touch override, element width) — replaced the spike's `ui_spike_*`. Extensions drive the substrate via `Host::ui()`. +- **The substrate does NOT own an inotify fd.** `UiSurfaceSpec::rml_path` asset + hot-reload (UNBOX_DEV-gated) is registered on the kernel's ONE shared + `FileWatcher` (`src/file_watcher.{hpp,cpp}`) — the same machinery that backs the + public `Host::watch_file`/`FileWatch` service (config hot-reload, UNGATED). Each + file-backed `Surface` holds a `FileWatch` whose callback flags it in + `pending_reloads`, applied (coalesced) at the next `tick_all` on the GL context. + ONE inotify instance per session, created lazily on the first watch (asset OR + watch_file). Only the *decision* to watch UI assets is UNBOX_DEV-gated; the + watcher infra is always available. Watches are dir-watches (editor temp+rename + safe) matched by basename; teardown order: extensions' FileWatch members → + substrate (surface FileWatches) → `Server::Impl::watcher.reset()` (removes the + wl_event_loop source while the loop is still alive) → display destroy. Shared GL/EGL/dmabuf lessons (carried from the spike, still load-bearing): -- cgit v1.2.3