sync: document spurious failures in oneshot (#4777)

This commit is contained in:
Alice Ryhl 2022-06-19 16:07:35 +02:00 committed by GitHub
parent d8fb721de2
commit 34b8ebbe66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 1 deletions

View File

@ -229,6 +229,14 @@ pub struct Sender<T> {
/// This channel has no `recv` method because the receiver itself implements the
/// [`Future`] trait. To receive a value, `.await` the `Receiver` object directly.
///
/// The `poll` method on the `Future` trait is allowed to spuriously return
/// `Poll::Pending` even if the message has been sent. If such a spurious
/// failure happens, then the caller will be woken when the spurious failure has
/// been resolved so that the caller can attempt to receive the message again.
/// Note that receiving such a wakeup does not guarantee that the next call will
/// succeed — it could fail with another spurious failure. (A spurious failure
/// does not mean that the message is lost. It is just delayed.)
///
/// [`Future`]: trait@std::future::Future
///
/// # Examples
@ -923,12 +931,16 @@ impl<T> Receiver<T> {
/// This function is useful to call from outside the context of an
/// asynchronous task.
///
/// Note that unlike the `poll` method, the `try_recv` method cannot fail
/// spuriously. Any send or close event that happens before this call to
/// `try_recv` will be correctly returned to the caller.
///
/// # Return
///
/// - `Ok(T)` if a value is pending in the channel.
/// - `Err(TryRecvError::Empty)` if no value has been sent yet.
/// - `Err(TryRecvError::Closed)` if the sender has dropped without sending
/// a value.
/// a value, or if the message has already been received.
///
/// # Examples
///

View File

@ -212,6 +212,18 @@ fn try_recv_after_completion() {
rx.close();
}
#[test]
fn try_recv_after_completion_await() {
let (tx, rx) = oneshot::channel::<i32>();
let mut rx = task::spawn(rx);
tx.send(17).unwrap();
assert_eq!(Ok(17), assert_ready!(rx.poll()));
assert_eq!(Err(TryRecvError::Closed), rx.try_recv());
rx.close();
}
#[test]
fn drops_tasks() {
let (mut tx, mut rx) = oneshot::channel::<i32>();