@@ -1321,12 +1321,13 @@ impl<T> Receiver<T> {
1321
1321
// Do an optimistic try_recv to avoid the performance impact of
1322
1322
// Instant::now() in the full-channel case.
1323
1323
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
+ } ,
1330
1331
}
1331
1332
}
1332
1333
@@ -2311,6 +2312,17 @@ mod tests {
2311
2312
assert_eq ! ( recv_count, stress) ;
2312
2313
}
2313
2314
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
+
2314
2326
#[ test]
2315
2327
fn recv_a_lot ( ) {
2316
2328
// Regression test that we don't run out of stack in scheduler context
0 commit comments