Skip to content

Commit 018f8a0

Browse files
committed
Use checked_add for adding time in recv_timeout
1 parent 7d03617 commit 018f8a0

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

src/libstd/sync/mpsc/mod.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -1321,12 +1321,13 @@ impl<T> Receiver<T> {
13211321
// Do an optimistic try_recv to avoid the performance impact of
13221322
// Instant::now() in the full-channel case.
13231323
match self.try_recv() {
1324-
Ok(result)
1325-
=> Ok(result),
1326-
Err(TryRecvError::Disconnected)
1327-
=> Err(RecvTimeoutError::Disconnected),
1328-
Err(TryRecvError::Empty)
1329-
=> self.recv_deadline(Instant::now() + timeout)
1324+
Ok(result) => Ok(result),
1325+
Err(TryRecvError::Disconnected) => Err(RecvTimeoutError::Disconnected),
1326+
Err(TryRecvError::Empty) => match Instant::now().checked_add(timeout) {
1327+
Some(deadline) => self.recv_deadline(deadline),
1328+
// So far in the future that it's practically the same as waiting indefinitely.
1329+
None => self.recv().map_err(RecvTimeoutError::from),
1330+
},
13301331
}
13311332
}
13321333

@@ -2311,6 +2312,17 @@ mod tests {
23112312
assert_eq!(recv_count, stress);
23122313
}
23132314

2315+
#[test]
2316+
fn very_long_recv_timeout_wont_panic() {
2317+
let (tx, rx) = channel::<()>();
2318+
let join_handle = thread::spawn(move || {
2319+
rx.recv_timeout(Duration::from_secs(u64::max_value()))
2320+
});
2321+
thread::sleep(Duration::from_secs(1));
2322+
assert!(tx.send(()).is_ok());
2323+
assert_eq!(join_handle.join().unwrap(), Ok(()));
2324+
}
2325+
23142326
#[test]
23152327
fn recv_a_lot() {
23162328
// Regression test that we don't run out of stack in scheduler context

0 commit comments

Comments
 (0)