diff --git a/tokio/src/sync/oneshot.rs b/tokio/src/sync/oneshot.rs index 20d39dc1a1e..4954da67ec2 100644 --- a/tokio/src/sync/oneshot.rs +++ b/tokio/src/sync/oneshot.rs @@ -443,6 +443,9 @@ impl Receiver { /// This function is useful to perform a graceful shutdown and ensure that a /// value will not be sent into the channel and never received. /// + /// `close` is no-op if a message is already received or the channel + /// is already closed. + /// /// [`Sender`]: Sender /// [`try_recv`]: Receiver::try_recv /// @@ -490,8 +493,9 @@ impl Receiver { /// } /// ``` pub fn close(&mut self) { - let inner = self.inner.as_ref().unwrap(); - inner.close(); + if let Some(inner) = self.inner.as_ref() { + inner.close(); + } } /// Attempts to receive a value. diff --git a/tokio/tests/sync_oneshot.rs b/tokio/tests/sync_oneshot.rs index 195c2553145..b1ea46a46ef 100644 --- a/tokio/tests/sync_oneshot.rs +++ b/tokio/tests/sync_oneshot.rs @@ -180,6 +180,16 @@ fn close_try_recv_poll() { let _ = rx.poll(); } +#[test] +fn close_after_recv() { + let (tx, mut rx) = oneshot::channel::(); + + tx.send(17).unwrap(); + + assert_eq!(17, rx.try_recv().unwrap()); + rx.close(); +} + #[test] fn drops_tasks() { let (mut tx, mut rx) = oneshot::channel::();