]> git.lizzy.rs Git - rust.git/commitdiff
std: Don't fail the task when a Future is dropped
authorAlex Crichton <alex@alexcrichton.com>
Mon, 16 Jun 2014 20:24:31 +0000 (13:24 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 17 Jun 2014 01:16:14 +0000 (18:16 -0700)
It's a benign failure that no one needs to know about.

Closes #14892

src/libstd/sync/future.rs

index bc748324fcd2b3ebffb40ab94a516aa4668d2a36..ccc67e3f8b01cb8671c1d7dbfb3aadbf7c134728 100644 (file)
@@ -132,7 +132,8 @@ pub fn spawn(blk: proc():Send -> A) -> Future<A> {
         let (tx, rx) = channel();
 
         spawn(proc() {
-            tx.send(blk());
+            // Don't fail if the other end has hung up
+            let _ = tx.send_opt(blk());
         });
 
         Future::from_receiver(rx)
@@ -144,6 +145,7 @@ mod test {
     use prelude::*;
     use sync::Future;
     use task;
+    use comm::{channel, Sender};
 
     #[test]
     fn test_from_value() {
@@ -206,4 +208,28 @@ fn test_sendable_future() {
             assert_eq!(actual, expected);
         });
     }
+
+    #[test]
+    fn test_dropped_future_doesnt_fail() {
+        struct Bomb(Sender<bool>);
+
+        local_data_key!(LOCAL: Bomb)
+
+        impl Drop for Bomb {
+            fn drop(&mut self) {
+                let Bomb(ref tx) = *self;
+                tx.send(task::failing());
+            }
+        }
+
+        // Spawn a future, but drop it immediately. When we receive the result
+        // later on, we should never view the task as having failed.
+        let (tx, rx) = channel();
+        drop(Future::spawn(proc() {
+            LOCAL.replace(Some(Bomb(tx)));
+        }));
+
+        // Make sure the future didn't fail the task.
+        assert!(!rx.recv());
+    }
 }