Remove unnecessary unwind messages

Now that the type_id intrinsic is working across crates, all of these
unnecessary messages can be removed to have the failure type for a task truly be
~Any and only ~Any
This commit is contained in:
Alex Crichton 2013-11-01 11:20:01 -07:00
parent 61637439dc
commit b00449380f
5 changed files with 41 additions and 76 deletions

View file

@ -20,7 +20,6 @@ use util::Void;
///////////////////////////////////////////////////////////////////////////////
// TypeId
// FIXME: #9913 - Needs proper intrinsic support to work reliably cross crate
///////////////////////////////////////////////////////////////////////////////
/// `TypeId` represents a globally unique identifier for a type
@ -199,8 +198,10 @@ mod tests {
#[test]
fn type_id() {
let (a, b, c) = (TypeId::of::<uint>(), TypeId::of::<&str>(), TypeId::of::<Test>());
let (d, e, f) = (TypeId::of::<uint>(), TypeId::of::<&str>(), TypeId::of::<Test>());
let (a, b, c) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
TypeId::of::<Test>());
let (d, e, f) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
TypeId::of::<Test>());
assert!(a != b);
assert!(a != c);

View file

@ -155,9 +155,9 @@ use cell::Cell;
use option::{Option, Some, None};
use prelude::*;
use rt::task::Task;
use rt::task::UnwindMessageLinked;
use rt::task::{UnwindResult, Failure};
use task::spawn::Taskgroup;
use task::LinkedFailure;
use to_bytes::IterBytes;
use unstable::atomics::{AtomicUint, Relaxed};
use unstable::sync::{UnsafeArc, UnsafeArcSelf, UnsafeArcT, LittleLock};
@ -597,7 +597,7 @@ impl Death {
}
if !success {
result = Cell::new(Failure(UnwindMessageLinked));
result = Cell::new(Failure(~LinkedFailure as ~Any));
}
}
on_exit(result.take());

View file

@ -36,6 +36,7 @@ use rt::logging::StdErrLogger;
use rt::sched::{Scheduler, SchedHandle};
use rt::stack::{StackSegment, StackPool};
use send_str::SendStr;
use task::LinkedFailure;
use task::spawn::Taskgroup;
use unstable::finally::Finally;
@ -95,8 +96,8 @@ pub enum UnwindResult {
/// The task is ending successfully
Success,
/// The Task is failing with reason `UnwindMessage`
Failure(UnwindMessage),
/// The Task is failing with reason `~Any`
Failure(~Any),
}
impl UnwindResult {
@ -119,27 +120,9 @@ impl UnwindResult {
}
}
/// Represents the cause of a task failure
#[deriving(ToStr)]
pub enum UnwindMessage {
// FIXME: #9913 - This variant is not neccessary once Any works properly
/// Failed with a static string message
UnwindMessageStrStatic(&'static str),
// FIXME: #9913 - This variant is not neccessary once Any works properly
/// Failed with a owned string message
UnwindMessageStrOwned(~str),
/// Failed with an `~Any`
UnwindMessageAny(~Any),
/// Failed because of linked failure
UnwindMessageLinked
}
pub struct Unwinder {
unwinding: bool,
cause: Option<UnwindMessage>
cause: Option<~Any>
}
impl Unwinder {
@ -532,7 +515,7 @@ impl Unwinder {
}
}
pub fn begin_unwind(&mut self, cause: UnwindMessage) -> ! {
pub fn begin_unwind(&mut self, cause: ~Any) -> ! {
#[fixed_stack_segment]; #[inline(never)];
self.unwinding = true;
@ -648,46 +631,34 @@ pub fn begin_unwind_raw(msg: *c_char, file: *c_char, line: size_t) -> ! {
/// This is the entry point of unwinding for fail!() and assert!().
pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> ! {
// Wrap the fail message in a `Any` box for uniform representation.
let any = ~msg as ~Any;
// FIXME: #9913 - This can be changed to be internal to begin_unwind_internal
// once Any works properly.
// As a workaround, string types need to be special cased right now
// because `Any` does not support dynamically querying whether the
// type implements a trait yet, so without requiring that every `Any`
// also implements `ToStr` there is no way to get a failure message
// out of it again during unwinding.
let msg = if any.is::<&'static str>() {
UnwindMessageStrStatic(*any.move::<&'static str>().unwrap())
} else if any.is::<~str>() {
UnwindMessageStrOwned(*any.move::<~str>().unwrap())
} else {
UnwindMessageAny(any)
};
begin_unwind_internal(msg, file, line)
}
fn begin_unwind_internal(msg: UnwindMessage, file: &'static str, line: uint) -> ! {
use any::AnyRefExt;
use rt::in_green_task_context;
use rt::task::Task;
use rt::local::Local;
use rt::task::Task;
use str::Str;
use unstable::intrinsics;
unsafe {
// Be careful not to allocate in this block, if we're failing we may
// have been failing due to a lack of memory in the first place...
let task: *mut Task;
// Note that this should be the only allocation performed in this block.
// Currently this means that fail!() on OOM will invoke this code path,
// but then again we're not really ready for failing on OOM anyway. If
// we do start doing this, then we should propagate this allocation to
// be performed in the parent of this task instead of the task that's
// failing.
let msg = ~msg as ~Any;
{
let msg_s = match msg {
UnwindMessageAny(_) => "~Any",
UnwindMessageLinked => "linked failure",
UnwindMessageStrOwned(ref s) => s.as_slice(),
UnwindMessageStrStatic(ref s) => s.as_slice(),
//let msg: &Any = msg;
let msg_s = match msg.as_ref::<&'static str>() {
Some(s) => *s,
None => match msg.as_ref::<~str>() {
Some(s) => s.as_slice(),
None => match msg.as_ref::<LinkedFailure>() {
Some(*) => "linked failure",
None => "~Any",
}
}
};
if !in_green_task_context() {

View file

@ -60,8 +60,6 @@ use comm::{stream, Chan, GenericChan, GenericPort, Port, Peekable};
use result::{Result, Ok, Err};
use rt::in_green_task_context;
use rt::local::Local;
use rt::task::{UnwindMessageAny, UnwindMessageLinked};
use rt::task::{UnwindMessageStrStatic, UnwindMessageStrOwned};
use rt::task::{UnwindResult, Success, Failure};
use send_str::{SendStr, IntoSendStr};
use unstable::finally::Finally;
@ -90,30 +88,25 @@ pub type TaskResult = Result<(), ~Any>;
pub struct LinkedFailure;
#[inline]
fn wrap_as_any(res: UnwindResult) -> TaskResult {
match res {
Success => Ok(()),
Failure(UnwindMessageAny(a)) => Err(a),
Failure(UnwindMessageLinked) => Err(~LinkedFailure as ~Any),
Failure(UnwindMessageStrOwned(s)) => Err(~s as ~Any),
Failure(UnwindMessageStrStatic(s)) => Err(~s as ~Any),
}
}
pub struct TaskResultPort {
priv port: Port<UnwindResult>
}
fn to_task_result(res: UnwindResult) -> TaskResult {
match res {
Success => Ok(()), Failure(a) => Err(a),
}
}
impl GenericPort<TaskResult> for TaskResultPort {
#[inline]
fn recv(&self) -> TaskResult {
wrap_as_any(self.port.recv())
to_task_result(self.port.recv())
}
#[inline]
fn try_recv(&self) -> Option<TaskResult> {
self.port.try_recv().map(wrap_as_any)
self.port.try_recv().map(to_task_result)
}
}

View file

@ -83,11 +83,11 @@ use local_data;
use rt::local::Local;
use rt::sched::{Scheduler, Shutdown, TaskFromFriend};
use rt::task::{Task, Sched};
use rt::task::{UnwindMessageLinked, UnwindMessageStrStatic};
use rt::task::{UnwindResult, Success, Failure};
use rt::thread::Thread;
use rt::work_queue::WorkQueue;
use rt::{in_green_task_context, new_event_loop, KillHandle};
use task::LinkedFailure;
use task::SingleThreaded;
use task::TaskOpts;
use task::unkillable;
@ -324,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.task_result = Some(Failure(UnwindMessageLinked));
x.task_result = Some(Failure(~LinkedFailure as ~Any));
}
// Take everybody down with us. After this point, every
// other task in the group will see 'tg' as none, which
@ -379,7 +379,7 @@ impl AutoNotify {
notify_chan: chan,
// Un-set above when taskgroup successfully made.
task_result: Some(Failure(UnwindMessageStrStatic("AutoNotify::new()")))
task_result: Some(Failure(~("AutoNotify::new()") as ~Any))
}
}
}