about summary refs log tree commit diff
path: root/src/libstd/rt/kill.rs
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-12-05 18:19:06 -0800
committerAlex Crichton <alex@alexcrichton.com>2013-12-16 17:47:11 -0800
commit529e268ab900f1b6e731af64ce2aeecda3555f4e (patch)
tree7ebb9ed2a7f36455b9550749a442522d45f0dc30 /src/libstd/rt/kill.rs
parentbfa9064ba2687eb1d95708f72f41ddd9729a6ba1 (diff)
Fallout of rewriting std::comm
Diffstat (limited to 'src/libstd/rt/kill.rs')
-rw-r--r--src/libstd/rt/kill.rs37
1 files changed, 23 insertions, 14 deletions
diff --git a/src/libstd/rt/kill.rs b/src/libstd/rt/kill.rs
index e3f9cd09632..f4f128cf5aa 100644
--- a/src/libstd/rt/kill.rs
+++ b/src/libstd/rt/kill.rs
@@ -153,8 +153,9 @@ There are two known issues with the current scheme for exit code propagation.
 use cast;
 use option::{Option, Some, None};
 use prelude::*;
+use iter;
+use task::TaskResult;
 use rt::task::Task;
-use rt::task::UnwindResult;
 use unstable::atomics::{AtomicUint, SeqCst};
 use unstable::sync::UnsafeArc;
 
@@ -169,11 +170,21 @@ pub enum BlockedTask {
 pub struct Death {
     // Action to be done with the exit code. If set, also makes the task wait
     // until all its watched children exit before collecting the status.
-    on_exit:         Option<proc(UnwindResult)>,
+    on_exit:         Option<proc(TaskResult)>,
     // nesting level counter for unstable::atomically calls (0 == can deschedule).
     priv wont_sleep:      int,
 }
 
+pub struct BlockedTaskIterator {
+    priv inner: UnsafeArc<AtomicUint>,
+}
+
+impl Iterator<BlockedTask> for BlockedTaskIterator {
+    fn next(&mut self) -> Option<BlockedTask> {
+        Some(Shared(self.inner.clone()))
+    }
+}
+
 impl BlockedTask {
     /// Returns Some if the task was successfully woken; None if already killed.
     pub fn wake(self) -> Option<~Task> {
@@ -194,19 +205,17 @@ impl BlockedTask {
     }
 
     /// Converts one blocked task handle to a list of many handles to the same.
-    pub fn make_selectable(self, num_handles: uint) -> ~[BlockedTask] {
-        let handles = match self {
+    pub fn make_selectable(self, num_handles: uint)
+        -> iter::Take<BlockedTaskIterator>
+    {
+        let arc = match self {
             Owned(task) => {
-                let flag = unsafe {
-                    AtomicUint::new(cast::transmute(task))
-                };
-                UnsafeArc::newN(flag, num_handles)
+                let flag = unsafe { AtomicUint::new(cast::transmute(task)) };
+                UnsafeArc::new(flag)
             }
-            Shared(arc) => arc.cloneN(num_handles),
+            Shared(arc) => arc.clone(),
         };
-        // Even if the task was unkillable before, we use 'Killable' because
-        // multiple pipes will have handles. It does not really mean killable.
-        handles.move_iter().map(|x| Shared(x)).collect()
+        BlockedTaskIterator{ inner: arc }.take(num_handles)
     }
 
     // This assertion has two flavours because the wake involves an atomic op.
@@ -254,10 +263,10 @@ impl Death {
     }
 
     /// Collect failure exit codes from children and propagate them to a parent.
-    pub fn collect_failure(&mut self, result: UnwindResult) {
+    pub fn collect_failure(&mut self, result: TaskResult) {
         match self.on_exit.take() {
+            Some(f) => f(result),
             None => {}
-            Some(on_exit) => on_exit(result),
         }
     }