Skip to content

Commit 56a1d53

Browse files
committed
Added receive_timeout to receiver
1 parent a763187 commit 56a1d53

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

src/reactive/channel.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ use std::ops::ControlFlow;
9292
use std::pin::Pin;
9393
use std::sync::Arc;
9494
use std::task::{ready, Context, Poll, Waker};
95+
use std::time::{Duration, Instant};
9596

9697
use builder::Builder;
9798
use parking_lot::{Condvar, Mutex, MutexGuard};
@@ -1449,10 +1450,53 @@ where
14491450
.ok()
14501451
}
14511452

1453+
/// Returns the next value if it can be retrieved within `timeout`.
1454+
///
1455+
/// # Errors
1456+
///
1457+
/// - [`TryReceiveError::Disconnected`] is returned if no senders are
1458+
/// connected to this receiver.
1459+
/// - [`TryReceiveError::Empty`] is returned if `timeout` elapses before a
1460+
/// value is received.
1461+
pub fn receive_timeout(&self, timeout: Duration) -> Result<T, TryReceiveError> {
1462+
self.receive_until(Instant::now() + timeout)
1463+
}
1464+
1465+
/// Returns the next value if it can be retrieved before `instant`.
1466+
///
1467+
/// If a value is already available, it will be returned even if `instant`
1468+
/// is in the past when this function is invoked. The timeout logic only is
1469+
/// applied when the queue is empty.
1470+
///
1471+
/// # Errors
1472+
///
1473+
/// - [`TryReceiveError::Disconnected`] is returned if no senders are
1474+
/// connected to this receiver.
1475+
/// - [`TryReceiveError::Empty`] is returned if `timeout` elapses before a
1476+
/// value is received.
1477+
pub fn receive_until(&self, instant: Instant) -> Result<T, TryReceiveError> {
1478+
let mut timed_out = false;
1479+
self.try_receive_inner(|guard| {
1480+
if self.data.condvar.wait_until(guard, instant).timed_out() {
1481+
timed_out = true;
1482+
ControlFlow::Break(())
1483+
} else {
1484+
ControlFlow::Continue(())
1485+
}
1486+
})
1487+
}
1488+
14521489
/// Returns the next value if possible, otherwise returning an error
14531490
/// describing why a value was unable to be received.
14541491
///
14551492
/// This function will not block the current thread.
1493+
///
1494+
/// # Errors
1495+
///
1496+
/// - [`TryReceiveError::Disconnected`] is returned if no senders are
1497+
/// connected to this receiver.
1498+
/// - [`TryReceiveError::Empty`] is returned if no value is available in
1499+
/// this channel.
14561500
pub fn try_receive(&self) -> Result<T, TryReceiveError> {
14571501
self.try_receive_inner(|_guard| ControlFlow::Break(()))
14581502
}

0 commit comments

Comments
 (0)