diff options
| author | bors <bors@rust-lang.org> | 2013-08-01 06:01:39 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-08-01 06:01:39 -0700 |
| commit | 18d124b9b5dcb9915e5e1489eed81ed6a8b90c39 (patch) | |
| tree | 08815543f7ba4e527622ab5c654f87b17d91c252 /src/libstd/task | |
| parent | 9824d90ffd7684eca7171c4e019fd85b9317904e (diff) | |
| parent | bc7cee7bbf816be7a712c06a93015dc3c6fd5611 (diff) | |
| download | rust-18d124b9b5dcb9915e5e1489eed81ed6a8b90c39.tar.gz rust-18d124b9b5dcb9915e5e1489eed81ed6a8b90c39.zip | |
auto merge of #8158 : bblum/rust/task-cleanup, r=brson
r? @brson
Diffstat (limited to 'src/libstd/task')
| -rw-r--r-- | src/libstd/task/mod.rs | 112 | ||||
| -rw-r--r-- | src/libstd/task/spawn.rs | 2 |
2 files changed, 59 insertions, 55 deletions
diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs index 6de0c78d00b..aff4bc12039 100644 --- a/src/libstd/task/mod.rs +++ b/src/libstd/task/mod.rs @@ -120,6 +120,8 @@ pub struct SchedOpts { * * * notify_chan - Enable lifecycle notifications on the given channel * + * * name - A name for the task-to-be, for identification in failure messages. + * * * sched - Specify the configuration of a new scheduler to create the task * in * @@ -139,6 +141,7 @@ pub struct TaskOpts { watched: bool, indestructible: bool, notify_chan: Option<Chan<TaskResult>>, + name: Option<~str>, sched: SchedOpts } @@ -185,6 +188,7 @@ impl TaskBuilder { self.consumed = true; let gen_body = self.gen_body.take(); let notify_chan = self.opts.notify_chan.take(); + let name = self.opts.name.take(); TaskBuilder { opts: TaskOpts { linked: self.opts.linked, @@ -192,6 +196,7 @@ impl TaskBuilder { watched: self.opts.watched, indestructible: self.opts.indestructible, notify_chan: notify_chan, + name: name, sched: self.opts.sched }, gen_body: gen_body, @@ -199,9 +204,7 @@ impl TaskBuilder { consumed: false } } -} -impl TaskBuilder { /// Decouple the child task's failure from the parent's. If either fails, /// the other will not be killed. pub fn unlinked(&mut self) { @@ -281,6 +284,12 @@ impl TaskBuilder { self.opts.notify_chan = Some(notify_pipe_ch); } + /// Name the task-to-be. Currently the name is used for identification + /// only in failure messages. + pub fn name(&mut self, name: ~str) { + self.opts.name = Some(name); + } + /// Configure a custom scheduler mode for the task. pub fn sched_mode(&mut self, mode: SchedMode) { self.opts.sched.mode = mode; @@ -333,6 +342,7 @@ impl TaskBuilder { pub fn spawn(&mut self, f: ~fn()) { let gen_body = self.gen_body.take(); let notify_chan = self.opts.notify_chan.take(); + let name = self.opts.name.take(); let x = self.consume(); let opts = TaskOpts { linked: x.opts.linked, @@ -340,6 +350,7 @@ impl TaskBuilder { watched: x.opts.watched, indestructible: x.opts.indestructible, notify_chan: notify_chan, + name: name, sched: x.opts.sched }; let f = match gen_body { @@ -408,6 +419,7 @@ pub fn default_task_opts() -> TaskOpts { watched: true, indestructible: false, notify_chan: None, + name: None, sched: SchedOpts { mode: DefaultScheduler, } @@ -507,6 +519,21 @@ pub fn try<T:Send>(f: ~fn() -> T) -> Result<T,()> { /* Lifecycle functions */ +/// Read the name of the current task. +pub fn with_task_name<U>(blk: &fn(Option<&str>) -> U) -> U { + use rt::task::Task; + + match context() { + TaskContext => do Local::borrow::<Task, U> |task| { + match task.name { + Some(ref name) => blk(Some(name.as_slice())), + None => blk(None) + } + }, + _ => fail!("no task name exists in %?", context()), + } +} + pub fn yield() { //! Yield control to the task scheduler @@ -628,44 +655,6 @@ pub unsafe fn rekillable<U>(f: &fn() -> U) -> U { } } -/** - * A stronger version of unkillable that also inhibits scheduling operations. - * For use with exclusive Arcs, which use pthread mutexes directly. - */ -pub unsafe fn atomically<U>(f: &fn() -> U) -> U { - use rt::task::Task; - - match context() { - OldTaskContext => { - let t = rt::rust_get_task(); - do (|| { - rt::rust_task_inhibit_kill(t); - rt::rust_task_inhibit_yield(t); - f() - }).finally { - rt::rust_task_allow_yield(t); - rt::rust_task_allow_kill(t); - } - } - TaskContext => { - let t = Local::unsafe_borrow::<Task>(); - do (|| { - // It's important to inhibit kill after inhibiting yield, because - // inhibit-kill might fail if we were already killed, and the - // inhibit-yield must happen to match the finally's allow-yield. - (*t).death.inhibit_yield(); - (*t).death.inhibit_kill((*t).unwinder.unwinding); - f() - }).finally { - (*t).death.allow_kill((*t).unwinder.unwinding); - (*t).death.allow_yield(); - } - } - // FIXME(#3095): As in unkillable(). - _ => f() - } -} - #[test] #[should_fail] #[ignore(cfg(windows))] fn test_cant_dup_task_builder() { let mut builder = task(); @@ -806,6 +795,34 @@ fn test_spawn_linked_sup_propagate_sibling() { } #[test] +fn test_unnamed_task() { + use rt::test::run_in_newsched_task; + + do run_in_newsched_task { + do spawn { + do with_task_name |name| { + assert!(name.is_none()); + } + } + } +} + +#[test] +fn test_named_task() { + use rt::test::run_in_newsched_task; + + do run_in_newsched_task { + let mut t = task(); + t.name(~"ada lovelace"); + do t.spawn { + do with_task_name |name| { + assert!(name.get() == "ada lovelace"); + } + } + } +} + +#[test] fn test_run_basic() { let (po, ch) = stream::<()>(); let mut builder = task(); @@ -1122,21 +1139,6 @@ fn test_unkillable_nested() { po.recv(); } -#[test] #[should_fail] #[ignore(cfg(windows))] -fn test_atomically() { - unsafe { do atomically { yield(); } } -} - -#[test] -fn test_atomically2() { - unsafe { do atomically { } } yield(); // shouldn't fail -} - -#[test] #[should_fail] #[ignore(cfg(windows))] -fn test_atomically_nested() { - unsafe { do atomically { do atomically { } yield(); } } -} - #[test] fn test_child_doesnt_ref_parent() { // If the child refcounts the parent task, this will stack overflow when diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index c7f34974a6e..81db5e690a6 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -725,6 +725,8 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) { task.death.on_exit = Some(on_exit); } + task.name = opts.name.take(); + rtdebug!("spawn about to take scheduler"); let sched = Local::take::<Scheduler>(); |
