Explain how locals alive across await become fields of the generated future
Keep a blocking mutex guard outside every suspension boundary
Make validation and overflow errors leave shared state unchanged
Send is derived from the suspended state
A multi-thread scheduler may resume a spawned future on another worker. The future is Send only when every value stored across a suspension point is Send. std::sync::MutexGuard is deliberately not Send, so using it after an await makes the whole future fail a spawn-style Send bound.
An async mutex does not excuse a long critical section
An async-aware guard may satisfy a runtime's type bounds, but keeping shared state locked during admission, network I/O, or backoff still serializes unrelated tasks and complicates cancellation. Put the await before the lock when the protocol permits, then validate, calculate, and commit without another suspension.
Choose the cancellation boundary deliberately
This reservation awaits admission before touching inventory. Cancellation before that await completes is state-neutral. After admission, one short synchronous critical section uses checked arithmetic and either commits both counters or returns an error without mutation.
CHECKPOINT
A multithreaded executor rejects an async reservation future because it is not Send. Which two review conclusions preserve the intended contract?
Select every applicable option. Credit requires an exact set match.
ISOLATED RUST 1.96
src/lib.rsEDIT
02 / DEBUGGING
Find and fix the defect
Repair `reserve_after_admission` without changing its public API. Zero units must fail before admission; the returned future must be Send; no mutex guard may survive an await; checked-arithmetic and poison errors must not mutate inventory; every success increments reserved units and revision exactly once.