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:
parent
61637439dc
commit
b00449380f
5 changed files with 41 additions and 76 deletions
|
@ -20,7 +20,6 @@ use util::Void;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// TypeId
|
// TypeId
|
||||||
// FIXME: #9913 - Needs proper intrinsic support to work reliably cross crate
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// `TypeId` represents a globally unique identifier for a type
|
/// `TypeId` represents a globally unique identifier for a type
|
||||||
|
@ -199,8 +198,10 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn type_id() {
|
fn type_id() {
|
||||||
let (a, b, c) = (TypeId::of::<uint>(), TypeId::of::<&str>(), TypeId::of::<Test>());
|
let (a, b, c) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
|
||||||
let (d, e, f) = (TypeId::of::<uint>(), TypeId::of::<&str>(), TypeId::of::<Test>());
|
TypeId::of::<Test>());
|
||||||
|
let (d, e, f) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
|
||||||
|
TypeId::of::<Test>());
|
||||||
|
|
||||||
assert!(a != b);
|
assert!(a != b);
|
||||||
assert!(a != c);
|
assert!(a != c);
|
||||||
|
|
|
@ -155,9 +155,9 @@ use cell::Cell;
|
||||||
use option::{Option, Some, None};
|
use option::{Option, Some, None};
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use rt::task::Task;
|
use rt::task::Task;
|
||||||
use rt::task::UnwindMessageLinked;
|
|
||||||
use rt::task::{UnwindResult, Failure};
|
use rt::task::{UnwindResult, Failure};
|
||||||
use task::spawn::Taskgroup;
|
use task::spawn::Taskgroup;
|
||||||
|
use task::LinkedFailure;
|
||||||
use to_bytes::IterBytes;
|
use to_bytes::IterBytes;
|
||||||
use unstable::atomics::{AtomicUint, Relaxed};
|
use unstable::atomics::{AtomicUint, Relaxed};
|
||||||
use unstable::sync::{UnsafeArc, UnsafeArcSelf, UnsafeArcT, LittleLock};
|
use unstable::sync::{UnsafeArc, UnsafeArcSelf, UnsafeArcT, LittleLock};
|
||||||
|
@ -597,7 +597,7 @@ impl Death {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !success {
|
if !success {
|
||||||
result = Cell::new(Failure(UnwindMessageLinked));
|
result = Cell::new(Failure(~LinkedFailure as ~Any));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
on_exit(result.take());
|
on_exit(result.take());
|
||||||
|
|
|
@ -36,6 +36,7 @@ use rt::logging::StdErrLogger;
|
||||||
use rt::sched::{Scheduler, SchedHandle};
|
use rt::sched::{Scheduler, SchedHandle};
|
||||||
use rt::stack::{StackSegment, StackPool};
|
use rt::stack::{StackSegment, StackPool};
|
||||||
use send_str::SendStr;
|
use send_str::SendStr;
|
||||||
|
use task::LinkedFailure;
|
||||||
use task::spawn::Taskgroup;
|
use task::spawn::Taskgroup;
|
||||||
use unstable::finally::Finally;
|
use unstable::finally::Finally;
|
||||||
|
|
||||||
|
@ -95,8 +96,8 @@ pub enum UnwindResult {
|
||||||
/// The task is ending successfully
|
/// The task is ending successfully
|
||||||
Success,
|
Success,
|
||||||
|
|
||||||
/// The Task is failing with reason `UnwindMessage`
|
/// The Task is failing with reason `~Any`
|
||||||
Failure(UnwindMessage),
|
Failure(~Any),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnwindResult {
|
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 {
|
pub struct Unwinder {
|
||||||
unwinding: bool,
|
unwinding: bool,
|
||||||
cause: Option<UnwindMessage>
|
cause: Option<~Any>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Unwinder {
|
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)];
|
#[fixed_stack_segment]; #[inline(never)];
|
||||||
|
|
||||||
self.unwinding = true;
|
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!().
|
/// 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) -> ! {
|
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.
|
use any::AnyRefExt;
|
||||||
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 rt::in_green_task_context;
|
use rt::in_green_task_context;
|
||||||
use rt::task::Task;
|
|
||||||
use rt::local::Local;
|
use rt::local::Local;
|
||||||
|
use rt::task::Task;
|
||||||
use str::Str;
|
use str::Str;
|
||||||
use unstable::intrinsics;
|
use unstable::intrinsics;
|
||||||
|
|
||||||
unsafe {
|
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;
|
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 {
|
//let msg: &Any = msg;
|
||||||
UnwindMessageAny(_) => "~Any",
|
let msg_s = match msg.as_ref::<&'static str>() {
|
||||||
UnwindMessageLinked => "linked failure",
|
Some(s) => *s,
|
||||||
UnwindMessageStrOwned(ref s) => s.as_slice(),
|
None => match msg.as_ref::<~str>() {
|
||||||
UnwindMessageStrStatic(ref s) => s.as_slice(),
|
Some(s) => s.as_slice(),
|
||||||
|
None => match msg.as_ref::<LinkedFailure>() {
|
||||||
|
Some(*) => "linked failure",
|
||||||
|
None => "~Any",
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if !in_green_task_context() {
|
if !in_green_task_context() {
|
||||||
|
|
|
@ -60,8 +60,6 @@ use comm::{stream, Chan, GenericChan, GenericPort, Port, Peekable};
|
||||||
use result::{Result, Ok, Err};
|
use result::{Result, Ok, Err};
|
||||||
use rt::in_green_task_context;
|
use rt::in_green_task_context;
|
||||||
use rt::local::Local;
|
use rt::local::Local;
|
||||||
use rt::task::{UnwindMessageAny, UnwindMessageLinked};
|
|
||||||
use rt::task::{UnwindMessageStrStatic, UnwindMessageStrOwned};
|
|
||||||
use rt::task::{UnwindResult, Success, Failure};
|
use rt::task::{UnwindResult, Success, Failure};
|
||||||
use send_str::{SendStr, IntoSendStr};
|
use send_str::{SendStr, IntoSendStr};
|
||||||
use unstable::finally::Finally;
|
use unstable::finally::Finally;
|
||||||
|
@ -90,30 +88,25 @@ pub type TaskResult = Result<(), ~Any>;
|
||||||
|
|
||||||
pub struct LinkedFailure;
|
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 {
|
pub struct TaskResultPort {
|
||||||
priv port: Port<UnwindResult>
|
priv port: Port<UnwindResult>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_task_result(res: UnwindResult) -> TaskResult {
|
||||||
|
match res {
|
||||||
|
Success => Ok(()), Failure(a) => Err(a),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl GenericPort<TaskResult> for TaskResultPort {
|
impl GenericPort<TaskResult> for TaskResultPort {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn recv(&self) -> TaskResult {
|
fn recv(&self) -> TaskResult {
|
||||||
wrap_as_any(self.port.recv())
|
to_task_result(self.port.recv())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn try_recv(&self) -> Option<TaskResult> {
|
fn try_recv(&self) -> Option<TaskResult> {
|
||||||
self.port.try_recv().map(wrap_as_any)
|
self.port.try_recv().map(to_task_result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,11 +83,11 @@ use local_data;
|
||||||
use rt::local::Local;
|
use rt::local::Local;
|
||||||
use rt::sched::{Scheduler, Shutdown, TaskFromFriend};
|
use rt::sched::{Scheduler, Shutdown, TaskFromFriend};
|
||||||
use rt::task::{Task, Sched};
|
use rt::task::{Task, Sched};
|
||||||
use rt::task::{UnwindMessageLinked, UnwindMessageStrStatic};
|
|
||||||
use rt::task::{UnwindResult, Success, Failure};
|
use rt::task::{UnwindResult, Success, Failure};
|
||||||
use rt::thread::Thread;
|
use rt::thread::Thread;
|
||||||
use rt::work_queue::WorkQueue;
|
use rt::work_queue::WorkQueue;
|
||||||
use rt::{in_green_task_context, new_event_loop, KillHandle};
|
use rt::{in_green_task_context, new_event_loop, KillHandle};
|
||||||
|
use task::LinkedFailure;
|
||||||
use task::SingleThreaded;
|
use task::SingleThreaded;
|
||||||
use task::TaskOpts;
|
use task::TaskOpts;
|
||||||
use task::unkillable;
|
use task::unkillable;
|
||||||
|
@ -324,7 +324,7 @@ impl Drop for Taskgroup {
|
||||||
do RuntimeGlue::with_task_handle_and_failing |me, failing| {
|
do RuntimeGlue::with_task_handle_and_failing |me, failing| {
|
||||||
if failing {
|
if failing {
|
||||||
for x in self.notifier.mut_iter() {
|
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
|
// Take everybody down with us. After this point, every
|
||||||
// other task in the group will see 'tg' as none, which
|
// other task in the group will see 'tg' as none, which
|
||||||
|
@ -379,7 +379,7 @@ impl AutoNotify {
|
||||||
notify_chan: chan,
|
notify_chan: chan,
|
||||||
|
|
||||||
// Un-set above when taskgroup successfully made.
|
// Un-set above when taskgroup successfully made.
|
||||||
task_result: Some(Failure(UnwindMessageStrStatic("AutoNotify::new()")))
|
task_result: Some(Failure(~("AutoNotify::new()") as ~Any))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue