From 95ce9e83c5aed221ddc7c32d0dbb6086a78b8f0c Mon Sep 17 00:00:00 2001 From: tv Date: Mon, 26 Oct 2026 21:45:25 +0100 Subject: document state lock order --- src/state/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/state/mod.rs b/src/state/mod.rs index 787fd8c..d4928a8 100644 --- a/src/state/mod.rs +++ b/src/state/mod.rs @@ -6,6 +6,17 @@ //! * `timing`: the intervals the protocol runs on (`Timing`). //! * `read`: serving reads, live or from the pre-rejoin copy. //! * `host`: the node as the remake module sees it (`remake::Host`). +//! +//! **Lock order.** Where several of these locks are held at once, they are taken in this +//! order: `doc` (the replica), `peer_states` (the map), a peer's `PeerState`, then +//! `lifecycle`. Sync generation and apply take doc → peer; an epoch switch doc → map → +//! each peer; establishing a peer peer → lifecycle. Waiting for a peer while holding the +//! map makes everything that needs the map wait for that peer, so apart from the switch +//! (which holds the map only for reading), code that walks the peers copies the map +//! first (`peers_snapshot`), and the one place that holds the map while looking at a +//! peer only tries its lock (`swarm::peer::forget_unless_alive`). The std mutexes +//! (statistics, round-trip times and the like) are held only briefly, never across an +//! await. mod host; mod peer; -- cgit v1.3.1