about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/sync/mpsc/mod.rs24
-rw-r--r--src/libstd/time.rs12
2 files changed, 30 insertions, 6 deletions
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index ecdf7e5668c..446c164965d 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -1311,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),
+            },
         }
     }
 
@@ -2302,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();
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index ffe604cd33b..eb67b718dbd 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -220,6 +220,12 @@ impl Instant {
 impl Add<Duration> for Instant {
     type Output = Instant;
 
+    /// # Panics
+    ///
+    /// This function may panic if the resulting point in time cannot be represented by the
+    /// underlying data structure. See [`checked_add`] for a version without panic.
+    ///
+    /// [`checked_add`]: ../../std/time/struct.Instant.html#method.checked_add
     fn add(self, other: Duration) -> Instant {
         self.checked_add(other)
             .expect("overflow when adding duration to instant")
@@ -387,6 +393,12 @@ impl SystemTime {
 impl Add<Duration> for SystemTime {
     type Output = SystemTime;
 
+    /// # Panics
+    ///
+    /// This function may panic if the resulting point in time cannot be represented by the
+    /// underlying data structure. See [`checked_add`] for a version without panic.
+    ///
+    /// [`checked_add`]: ../../std/time/struct.SystemTime.html#method.checked_add
     fn add(self, dur: Duration) -> SystemTime {
         self.checked_add(dur)
             .expect("overflow when adding duration to instant")