Struct async_condvar_fair::Baton [−][src]
pub struct Baton<'c> { /* fields omitted */ }
Expand description
Obligation to do work, or notify someone else to do it
Task cancellation in async Rust
In async Rust, futures can be cancelled at any await
point, and
simply discarded, if whatever was waiting for them loses interest.
From the point of view of a reader of the async
block, this is
as if the code simply stopped running at some await
point, for
reasons outside of its own control, and discarded all of its state.
When notify_one
is being used, there is therefore a risk that
the waiting task that notify_one
chooses to wake up gets
cancelled before it is able to do the work that the notifier
intended.
(This risk only arises if the process of responding to the
notification might await
. In that case you will also want to be
using an async mutex, since it is generally forbidden to
await
with a sync mutex held.)
Baton
helps with this risk. Option<Baton>
is returned by
wait_baton
, and should be kept until the work is completed, and
then dispose
d.
If the Baton
is simply dropped (for example, due to task
cancellation), the condvar will be re-notified.
How to handle a Baton
Use wait_baton
rather than plain wait
. When wait_baton
completes, keep the baton while you do whatever work there is to
be done.
After having done the necessary work, as the caller of
notify_one
was expecting, call Baton::dispose
.
Infinite loop, or even livelock, risk
It is important to dispose
of the baton even if your processing
suffers a (possibly persistent) error. If you accidentally drop the
baton (eg on an error path), another task will be woken up and
perhaps perform the same failing actions, leading to the program
looping uselessly, eating cpu.
Depending on your runtime’s scheduler, that might even be a livelock.
Implementations
Trait Implementations
Auto Trait Implementations
impl<'c> !RefUnwindSafe for Baton<'c>
impl<'c> !UnwindSafe for Baton<'c>