Add `oneshot::Receiver::try_recv`.
Attempts to receive a message outside of context of a task, such as
within a `Drop` impl. It does not schedule a task wakeup or have any
other side effects.
@@ -237,6 +237,23 @@ impl<T> Inner<T> {
}
}
+ fn try_recv(&self) -> Result<Option<T>, Canceled> {
+ // If we're complete, either `::close_rx` or `::drop_tx` was called.
+ // We can assume a successful send if data is present.
+ if self.complete.load(SeqCst) {
+ if let Some(mut slot) = self.data.try_lock() {
+ if let Some(data) = slot.take() {
+ return Ok(Some(data.into()));
+ }
+ }
+ // Should there be a different error value or a panic in the case
+ // where `self.data.try_lock() == None`?
+ Err(Canceled)
+ } else {
+ Ok(None)
+ }
+ }
+
fn recv(&self, cx: &mut task::Context) -> Poll<T, Canceled> {
let mut done = false;
@@ -331,8 +348,8 @@ impl<T> Sender<T> {
///
/// # Return values
///
- /// If `Ok(Ready)` is returnd then the associated `Receiver` has been dropped,
- /// which means any work required for sending should be cancelled.
+ /// If `Ok(Ready)` is returned then the associated `Receiver` has been
+ /// dropped, which means any work required for sending should be canceled.
///
/// If `Ok(Pending)` is returned then the associated `Receiver` is still
/// alive and may be able to receive a message if sent. The current task,
@@ -387,6 +404,21 @@ impl<T> Receiver<T> {
pub fn close(&mut self) {
self.inner.close_rx()
}
+
+ /// Attempts to receive a message outside of the context of a task.
+ ///
+ /// Useful when a [`Context`](Context) is not available such as within a
+ /// `Drop` impl.
+ ///
+ /// Does not schedule a task wakeup or have any other side effects.
+ ///
+ /// A return value of `None` must be considered immediately stale (out of
+ /// date) unless [`::close`](Receiver::close) has been called first.
+ ///
+ /// Returns an error if the sender was dropped.
+ pub fn try_recv(&mut self) -> Result<Option<T>, Canceled> {
+ self.inner.try_recv()
+ }
}
impl<T> Future for Receiver<T> {
