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 | 2d0d1f501d27c87d3810ec05129fdf79c52a61c6 (patch) | |
| tree | 9a07b6ae7062522ef648e8513769c8610f031c18 /src/state | |
| parent | b9671e10834d9656241066e10d2d95e3487e123e (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; |
