Skip to content

Commit

Permalink
sync: document spurious failures in oneshot (#4777)
Browse files Browse the repository at this point in the history
  • Loading branch information
Darksonn committed Jun 19, 2022
1 parent d8fb721 commit 34b8ebb
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
14 changes: 13 additions & 1 deletion tokio/src/sync/oneshot.rs
Expand Up @@ -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
Expand Down Expand Up @@ -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
///
Expand Down
12 changes: 12 additions & 0 deletions tokio/tests/sync_oneshot.rs
Expand Up @@ -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>();
Expand Down

0 comments on commit 34b8ebb

Please sign in to comment.