diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2013-12-05 18:19:06 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2013-12-16 17:47:11 -0800 |
| commit | 529e268ab900f1b6e731af64ce2aeecda3555f4e (patch) | |
| tree | 7ebb9ed2a7f36455b9550749a442522d45f0dc30 /src/libstd/rt/kill.rs | |
| parent | bfa9064ba2687eb1d95708f72f41ddd9729a6ba1 (diff) | |
Fallout of rewriting std::comm
Diffstat (limited to 'src/libstd/rt/kill.rs')
| -rw-r--r-- | src/libstd/rt/kill.rs | 37 |
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), } } |
