Don't require an allocation for on_exit messages

Instead, use an enum to allow running both a procedure and sending the task
result over a channel. I expect the common case to be sending on a channel (e.g.
task::try), so don't require an extra allocation in the common case.

cc #11389
This commit is contained in:
Alex Crichton 2014-02-10 14:49:56 -08:00
parent aaead93c45
commit 21a064d5a3
3 changed files with 16 additions and 12 deletions

View File

@ -22,7 +22,7 @@ use std::cast;
use std::rt::Runtime;
use std::rt::rtio;
use std::rt::local::Local;
use std::rt::task::{Task, BlockedTask};
use std::rt::task::{Task, BlockedTask, SendMessage};
use std::task::TaskOpts;
use std::unstable::mutex::Mutex;
@ -131,8 +131,7 @@ impl GreenTask {
task.stdout = stdout;
match notify_chan {
Some(chan) => {
let on_exit = proc(task_result) { chan.send(task_result) };
task.death.on_exit = Some(on_exit);
task.death.on_exit = Some(SendMessage(chan));
}
None => {}
}

View File

@ -18,7 +18,7 @@ use std::cast;
use std::rt::env;
use std::rt::local::Local;
use std::rt::rtio;
use std::rt::task::{Task, BlockedTask};
use std::rt::task::{Task, BlockedTask, SendMessage};
use std::rt::thread::Thread;
use std::rt;
use std::task::TaskOpts;
@ -68,10 +68,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {
task.stderr = stderr;
task.stdout = stdout;
match notify_chan {
Some(chan) => {
let on_exit = proc(task_result) { chan.send(task_result) };
task.death.on_exit = Some(on_exit);
}
Some(chan) => { task.death.on_exit = Some(SendMessage(chan)); }
None => {}
}

View File

@ -17,6 +17,7 @@ use any::AnyOwnExt;
use cast;
use cleanup;
use clone::Clone;
use comm::Chan;
use io::Writer;
use iter::{Iterator, Take};
use local_data;
@ -67,11 +68,17 @@ pub enum BlockedTask {
Shared(UnsafeArc<AtomicUint>),
}
pub enum DeathAction {
/// 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.
Execute(proc(TaskResult)),
/// A channel to send the result of the task on when the task exits
SendMessage(Chan<TaskResult>),
}
/// Per-task state related to task death, killing, failure, etc.
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(TaskResult)>,
on_exit: Option<DeathAction>,
}
pub struct BlockedTasks {
@ -381,7 +388,8 @@ impl Death {
/// Collect failure exit codes from children and propagate them to a parent.
pub fn collect_failure(&mut self, result: TaskResult) {
match self.on_exit.take() {
Some(f) => f(result),
Some(Execute(f)) => f(result),
Some(SendMessage(ch)) => { ch.try_send(result); }
None => {}
}
}