diff options
| author | tv <tv@krebsco.de> | 2026-10-26 21:45:25 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-26 21:45:25 +0100 |
| commit | 95ce9e83c5aed221ddc7c32d0dbb6086a78b8f0c (patch) | |
| tree | 831810c1c705e43675fe7e71b6c01daf96f15fe9 /src/state | |
| parent | 3374b029bea44fed6ad5a46a7a05c269ce61af58 (diff) | |
document state lock order
Diffstat (limited to 'src/state')
| -rw-r--r-- | src/state/mod.rs | 11 |
1 files changed, 11 insertions, 0 deletions
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; |
