host/observer: phase 3 I/O adapter (read-only registry observer)
Codex authored the adapter half of the phase-3 split; I reviewed it and applied one robustness fix (below). Additive/read-only — does not yet replace the existing audio.rs router (that migration is a later integration phase). adapter.rs: a dedicated libpipewire main-loop thread translating registry globals into RegEvents and publishing the latest Projection via RegistryObserverHandle::latest(). core.sync(0)/done is matched one-shot → ServerSynced; a 250 ms loop timer emits Tick for the fail-closed readiness timeout; pulse-PID candidates are probed from /proc/<pid>/comm only when the candidate changes; Links missing endpoint props are bound (LinkInfoRef, weak back-ref to avoid the listener cycle) and resolved via LinkEndpointsResolved. mod.rs: `pub mod adapter;`. audio.rs: parse_object_serial → pub(crate) so the adapter reuses the strict 64-bit parser. Review fix: record_global was called unconditionally per global (including unknown object types and dropped globals), which could desync the bound-link FIFO from the model's live_ids and leak a Link proxy on a recycled id. Now folded into `add()` so a slot is recorded only when an Added event is applied — the two id queues are provably lockstep. Exit gate complete: 5 pure rows + the live topology-diff row (row 6) — the #[ignore] adapter test PASSES on this host against the live daemon (module-null-sink + module-loopback observed appearing and disappearing). cargo test --bins 117 + 1 live green, clippy clean, no fmt sweep. Co-Authored-By: Codex (gpt-5.6-sol) <codex@openai.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -615,7 +615,7 @@ fn run_router(
|
||||
/// (empty, signed, whitespace-padded, non-numeric, overflowing) is a
|
||||
/// property we do not understand and must not guess at. Leading zeroes
|
||||
/// are accepted — they are unambiguous and parse to the same value.
|
||||
fn parse_object_serial(raw: &str) -> Option<u64> {
|
||||
pub(crate) fn parse_object_serial(raw: &str) -> Option<u64> {
|
||||
if raw.is_empty() || !raw.bytes().all(|b| b.is_ascii_digit()) {
|
||||
return None;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user