diff options
| author | Marvin Löbel <loebel.marvin@gmail.com> | 2013-10-11 23:20:34 +0200 |
|---|---|---|
| committer | Marvin Löbel <loebel.marvin@gmail.com> | 2013-10-28 08:50:32 +0100 |
| commit | fa8e71a8257f4226ab532d4bf268d3ecbfa98eb4 (patch) | |
| tree | 0b8051814dd8a5ef08e663c172e2b456065d625d /src/libstd/task/spawn.rs | |
| parent | cb5b21eba713ff3888b2741db4c9e7d841cfde02 (diff) | |
| download | rust-fa8e71a8257f4226ab532d4bf268d3ecbfa98eb4.tar.gz rust-fa8e71a8257f4226ab532d4bf268d3ecbfa98eb4.zip | |
Allow fail messages to be caught, and introduce the Any trait
Some code cleanup, sorting of import blocks Removed std::unstable::UnsafeArc's use of Either Added run-fail tests for the new FailWithCause impls Changed future_result and try to return Result<(), ~Any>. - Internally, there is an enum of possible fail messages passend around. - In case of linked failure or a string message, the ~Any gets lazyly allocated in future_results recv method. - For that, future result now returns a wrapper around a Port. - Moved and renamed task::TaskResult into rt::task::UnwindResult and made it an internal enum. - Introduced a replacement typedef `type TaskResult = Result<(), ~Any>`.
Diffstat (limited to 'src/libstd/task/spawn.rs')
| -rw-r--r-- | src/libstd/task/spawn.rs | 60 |
1 files changed, 34 insertions, 26 deletions
diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index fbe2988f77c..235e67048f6 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -76,21 +76,24 @@ use prelude::*; use cast::transmute; use cast; use cell::Cell; -use container::MutableMap; use comm::{Chan, GenericChan, oneshot}; +use container::MutableMap; use hashmap::{HashSet, HashSetMoveIterator}; use local_data; -use task::{Failure, SingleThreaded}; -use task::{Success, TaskOpts, TaskResult}; -use task::unkillable; -use uint; -use util; -use unstable::sync::Exclusive; use rt::in_green_task_context; use rt::local::Local; -use rt::task::{Task, Sched}; use rt::shouldnt_be_public::{Scheduler, KillHandle, WorkQueue, Thread, EventLoop}; +use rt::task::{Task, Sched}; +use rt::task::{UnwindReasonLinked, UnwindReasonStr}; +use rt::task::{UnwindResult, Success, Failure}; use rt::uv::uvio::UvEventLoop; +use send_str::IntoSendStr; +use task::SingleThreaded; +use task::TaskOpts; +use task::unkillable; +use uint; +use unstable::sync::Exclusive; +use util; #[cfg(test)] use task::default_task_opts; #[cfg(test)] use comm; @@ -321,7 +324,7 @@ impl Drop for Taskgroup { do RuntimeGlue::with_task_handle_and_failing |me, failing| { if failing { for x in self.notifier.mut_iter() { - x.failed = true; + x.task_result = Some(Failure(UnwindReasonLinked)); } // Take everybody down with us. After this point, every // other task in the group will see 'tg' as none, which @@ -353,7 +356,7 @@ pub fn Taskgroup(tasks: TaskGroupArc, ancestors: AncestorList, mut notifier: Option<AutoNotify>) -> Taskgroup { for x in notifier.mut_iter() { - x.failed = false; + x.task_result = Some(Success); } Taskgroup { @@ -364,21 +367,28 @@ pub fn Taskgroup(tasks: TaskGroupArc, } struct AutoNotify { - notify_chan: Chan<TaskResult>, - failed: bool, + notify_chan: Chan<UnwindResult>, + + // XXX: By value self drop would allow this to be a plain UnwindResult + task_result: Option<UnwindResult>, } -impl Drop for AutoNotify { - fn drop(&mut self) { - let result = if self.failed { Failure } else { Success }; - self.notify_chan.send(result); +impl AutoNotify { + pub fn new(chan: Chan<UnwindResult>) -> AutoNotify { + AutoNotify { + notify_chan: chan, + + // Un-set above when taskgroup successfully made. + task_result: Some(Failure(UnwindReasonStr("AutoNotify::new()".into_send_str()))) + } } } -fn AutoNotify(chan: Chan<TaskResult>) -> AutoNotify { - AutoNotify { - notify_chan: chan, - failed: true // Un-set above when taskgroup successfully made. +impl Drop for AutoNotify { + fn drop(&mut self) { + let result = self.task_result.take_unwrap(); + + self.notify_chan.send(result); } } @@ -675,10 +685,8 @@ pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) { if opts.notify_chan.is_some() { let notify_chan = opts.notify_chan.take_unwrap(); let notify_chan = Cell::new(notify_chan); - let on_exit: ~fn(bool) = |success| { - notify_chan.take().send( - if success { Success } else { Failure } - ) + let on_exit: ~fn(UnwindResult) = |task_result| { + notify_chan.take().send(task_result) }; task.death.on_exit = Some(on_exit); } @@ -721,7 +729,7 @@ fn test_spawn_raw_notify_success() { }; do spawn_raw(opts) { } - assert_eq!(notify_po.recv(), Success); + assert!(notify_po.recv().is_success()); } #[test] @@ -738,5 +746,5 @@ fn test_spawn_raw_notify_failure() { do spawn_raw(opts) { fail!(); } - assert_eq!(notify_po.recv(), Failure); + assert!(notify_po.recv().is_failure()); } |
