Repository navigation
refactor(rwlock): move guard permits into access tokens - #351
Conversation
|
Thanks for reworking this. The tokens make permit ownership easier to follow. I agree with @orthur2’s suggestion to use Deref/DerefMut for the projections and keep the safety explanations with the remaining raw accesses. I didn’t find a correctness issue. My validation and benchmark results for that revision are below. Validation
TradeoffsComparing
These are small, workload-specific differences, not evidence of a general slowdown. For the simpler ownership handling. Documentation nitCould we shorten the repeated rewrite explanations in the guard headers and |
orthur2
left a comment
There was a problem hiding this comment.
Thanks.The ownership transfers and downgrade ordering look sound to me.
On the owner representation, I'd prefer storing the owner directly, and doing it in this PR. That keeps the niche for Option, so the four try_* methods return the same size as before, and it removes the owner check from Deref and DerefMut on the unmapped guards. The cost moves to owned downgrade, which pays an extra Arc clone and drop, and to the two borrowed into_semaphore conversions, which need a mem::forget on a token that holds only a reference and a count. That seems a better place for the cost than ordinary guard use, and it still keeps the token design and drops every ptr::read.
75c73bb to
eb5cd4f
Compare
|
@orthur2, @QwQBiG, @ariesdevil sorry for spamming, but I changed the code according to your reviews and advices. I think the code is ready for now. |
|
LGTM, thanks! :3 |
orthur2
left a comment
There was a problem hiding this comment.
Thanks, looks good to me now.
Summary
Rework #289 on current
main. RwLock's eight guard types now hold a private access token that owns their permits and releases them on drop, so projecting or downgrading a guard moves its token instead of suppressing the guard's destructor. This removes all 20ManuallyDropwrappers and the 10 unsafeptr::readcalls that moved theArcout of owned guards. Unsafe blocks underrwlock/drop from 36 to 12, each one aDereforDerefMutbody with a SAFETY line; the newaccessmodule has none. Public API signatures, auto traits, guard sizes, and FIFO ordering are unchanged.As in #289, apply ASF source headers to the nine rewritten files while keeping the Tokio copyright, MIT attribution, and pinned upstream links, update the RwLock paragraph in
LICENSE, and remove the RwLock exemptions from the header checker. Replace the Tokio-derived documentation with the module-level guide and short item docs from #289; the three module examples replace the per-method examples, and each acquire method keeps the project's# Cancel safetysection.Add tests for real events around projected guards: a rejected
filter_mapthat hands the guard back, a cancelled reader or writer that holds a mapped guard while another request is queued, a projection that panics inside a spawned task, and a suspended task that owns a mapped guard and is then aborted. Together they use all eight guard types. Also keep #289's tests for downgrade at reader limits of 1, 3, andusize::MAX, cancellation of a granted owned request,get_mutandinto_inner, and mapped guardSendbounds. All of these tests also pass against the previous implementation.Design Notes
Tokens are the design from #289 with one change: a token stores its owner directly (a borrowed lock, a borrowed semaphore for borrowed projections, or an
Arc) rather than in anOption. This keeps the pointer niche, soOption<Guard>for the four unmapped guards is the guard's own size, andDerefhas noNonecheck. Borrowed projections copy the reference andmem::forgetthe old token, which holds only that reference and a permit count. Owned downgrade clones theArcand lets the old token release the remaining permits on drop. Downgrade creates the read token before it releases the other permits.Three things from #289 are left out because the Waker Contract no longer supports recovery from panicking wakers: the
CHANGELOGbug-fix entry, the sentence about wake-callback unwinding inLICENSE, and the panicking-waker regression test. The two macro-based projection tests are replaced by the scenario tests above.Validation:
cargo x test(593 passed),cargo x check,cargo x lint, and Miri onunsafe_paths_test.