diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index 51ee4a5178b..86347c7d3a6 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -6,8 +6,8 @@ * between tasks. */ -import unsafe::{SharedMutableState, - shared_mutable_state, clone_shared_mutable_state, +import unsafe::{SharedMutableState, shared_mutable_state, + clone_shared_mutable_state, unwrap_shared_mutable_state, get_shared_mutable_state, get_shared_immutable_state}; import sync; import sync::{mutex, mutex_with_condvars, rwlock, rwlock_with_condvars}; @@ -93,6 +93,12 @@ fn clone(rc: &arc) -> arc { arc { x: unsafe { clone_shared_mutable_state(&rc.x) } } } +#[cfg(stage1)] +fn unwrap(+rc: arc) -> T { + let arc { x: x } = rc; + unsafe { unwrap_shared_mutable_state(x) } +} + /**************************************************************************** * Mutex protected ARC (unsafe) ****************************************************************************/ @@ -181,6 +187,18 @@ impl &mutex_arc { } } +// FIXME(#2585) make this a by-move method on the arc +#[cfg(stage1)] +fn unwrap_mutex_arc(+arc: mutex_arc) -> T { + let mutex_arc { x: x } = arc; + let inner = unsafe { unwrap_shared_mutable_state(x) }; + let mutex_arc_inner { failed: failed, data: data, _ } = inner; + if failed { + fail ~"Can't unwrap poisoned mutex_arc - another task failed inside!" + } + data +} + // Common code for {mutex.access,rwlock.write}{,_cond}. #[inline(always)] #[doc(hidden)] @@ -347,6 +365,18 @@ impl &rw_arc { } } +// FIXME(#2585) make this a by-move method on the arc +#[cfg(stage1)] +fn unwrap_rw_arc(+arc: rw_arc) -> T { + let rw_arc { x: x, _ } = arc; + let inner = unsafe { unwrap_shared_mutable_state(x) }; + let rw_arc_inner { failed: failed, data: data, _ } = inner; + if failed { + fail ~"Can't unwrap poisoned rw_arc - another task failed inside!" + } + data +} + // Borrowck rightly complains about immutably aliasing the rwlock in order to // lock it. This wraps the unsafety, with the justification that the 'lock' // field is never overwritten; only 'failed' and 'data'. @@ -497,6 +527,22 @@ mod tests { } } #[test] #[should_fail] #[ignore(cfg(windows))] + #[cfg(stage1)] + fn test_mutex_arc_unwrap_poison() { + let arc = mutex_arc(1); + let arc2 = ~(&arc).clone(); + let (c,p) = pipes::stream(); + do task::spawn { + do arc2.access |one| { + c.send(()); + assert *one == 2; + } + } + let _ = p.recv(); + let one = unwrap_mutex_arc(arc); + assert one == 1; + } + #[test] #[should_fail] #[ignore(cfg(windows))] fn test_rw_arc_poison_wr() { let arc = ~rw_arc(1); let arc2 = ~arc.clone();