refactor: centralize lock-poison unwrap in crate::sync - #54
Merged
Conversation
`panic = "abort"` (release) means a std lock can never be observed poisoned, so the ~80 `.lock().unwrap()` / `.read()`/`.write()` `.unwrap()` call sites were provably-infallible noise repeated everywhere. Add `crate::sync` with thin `Mutex` / `RwLock` newtypes whose `lock` / `read` / `write` return the guard directly, moving that unwrap into one place. Call sites become plain `.lock()` / `.read()` / `.write()`, the "cannot actually fail" reasoning lives in one doc comment, and new code is clean by construction. Behavior is identical to the old per-site unwrap: infallible in release, loud fail-fast on the unwind-only poison path in debug. We deliberately do not recover via `into_inner` (that only helps an unwinding long-running server, moot when every panic aborts). Also turn three dead `if let Ok(_) = .lock()` poison-branches into unconditional locks. Left untouched on purpose: the async tokio `publish_lock`, and `web::SETTINGS_WRITE_LOCK`, which deliberately keeps std poison recovery so a panic mid-save can't wedge later config writes. clippy -D warnings clean, 282 tests green, release build OK.
Soulhackzlol
force-pushed
the
refactor/poison-free-locks
branch
from
August 16, 2026 21:57
b81ed61 to
25c1078
Compare
This branch centralizes the lock unwraps into crate::sync, so the "handful of unwrap() on lock guards, still on the cleanup list" line in Status is no longer true. Removed from both READMEs so the claim lands atomically with the code that makes it accurate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Centralizes the lock-poison
unwrapthat was repeated at ~80 call sites into a single place.panic = "abort"(release) means astdlock can never be observed poisoned, so every.lock().unwrap()/.read()/.write().unwrap()was provably-infallible noise, repeated everywhere and re-derived by each reader. This addscrate::syncwith thinMutex/RwLocknewtypes whoselock/read/writereturn the guard directly..lock()/.read()/.write().Behavior is identical to the old per-site unwrap: infallible in release, loud fail-fast on the unwind-only poison path in debug. It deliberately does not recover via
into_inner(that pattern only helps an unwinding long-running server, which is moot when every panic aborts the process).Also turns three dead
if let Ok(_) = .lock()poison-branches into unconditional locks.Deliberately left untouched
publish_lock(different primitive, uses.await).web::SETTINGS_WRITE_LOCK, which intentionally keepsstdpoison recovery so a panic mid-save can't wedge later config writes. It's the one place poison handling is a real choice, not noise, and its comment now says so.Testing
cargo clippy --all-targets -- -D warningsclean.#[inline]newtype over thestdlock, same layout and codegen.Notes
parking_loton purpose - its speed edge is irrelevant here since these locks are uncontended and the bottleneck is the syscall, and it would grow the dependency tree the project keeps minimal).