about summary refs log tree commit diff
path: root/src/libstd/sync/mpsc/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/sync/mpsc/mod.rs')
-rw-r--r--src/libstd/sync/mpsc/mod.rs34
1 files changed, 18 insertions, 16 deletions
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index 059ced4f56e..446c164965d 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -1,13 +1,3 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 //! Multi-producer, single-consumer FIFO queue communication primitives.
 //!
 //! This module provides message-based communication over channels, concretely
@@ -1321,12 +1311,13 @@ impl<T> Receiver<T> {
         // Do an optimistic try_recv to avoid the performance impact of
         // Instant::now() in the full-channel case.
         match self.try_recv() {
-            Ok(result)
-                => Ok(result),
-            Err(TryRecvError::Disconnected)
-                => Err(RecvTimeoutError::Disconnected),
-            Err(TryRecvError::Empty)
-                => self.recv_deadline(Instant::now() + timeout)
+            Ok(result) => Ok(result),
+            Err(TryRecvError::Disconnected) => Err(RecvTimeoutError::Disconnected),
+            Err(TryRecvError::Empty) => match Instant::now().checked_add(timeout) {
+                Some(deadline) => self.recv_deadline(deadline),
+                // So far in the future that it's practically the same as waiting indefinitely.
+                None => self.recv().map_err(RecvTimeoutError::from),
+            },
         }
     }
 
@@ -2312,6 +2303,17 @@ mod tests {
     }
 
     #[test]
+    fn very_long_recv_timeout_wont_panic() {
+        let (tx, rx) = channel::<()>();
+        let join_handle = thread::spawn(move || {
+            rx.recv_timeout(Duration::from_secs(u64::max_value()))
+        });
+        thread::sleep(Duration::from_secs(1));
+        assert!(tx.send(()).is_ok());
+        assert_eq!(join_handle.join().unwrap(), Ok(()));
+    }
+
+    #[test]
     fn recv_a_lot() {
         // Regression test that we don't run out of stack in scheduler context
         let (tx, rx) = channel();