diff options
| author | Ben Blum <bblum@andrew.cmu.edu> | 2012-08-20 17:58:59 -0400 |
|---|---|---|
| committer | Ben Blum <bblum@andrew.cmu.edu> | 2012-08-20 21:51:39 -0400 |
| commit | 1aa50bba7c11b8d3e2e66bd55913214fcb05a3cc (patch) | |
| tree | c08bb565cdda5915aa9b8afed4563068ecb14bb4 /src/libstd | |
| parent | 05accaa16787285560c6ddb1afe9dec45726a7f4 (diff) | |
| download | rust-1aa50bba7c11b8d3e2e66bd55913214fcb05a3cc.tar.gz rust-1aa50bba7c11b8d3e2e66bd55913214fcb05a3cc.zip | |
Add unwrap for std::arc ARC variants
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/arc.rs | 50 |
1 files changed, 48 insertions, 2 deletions
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<T: const send>(rc: &arc<T>) -> arc<T> { arc { x: unsafe { clone_shared_mutable_state(&rc.x) } } } +#[cfg(stage1)] +fn unwrap<T: const send>(+rc: arc<T>) -> T { + let arc { x: x } = rc; + unsafe { unwrap_shared_mutable_state(x) } +} + /**************************************************************************** * Mutex protected ARC (unsafe) ****************************************************************************/ @@ -181,6 +187,18 @@ impl<T: send> &mutex_arc<T> { } } +// FIXME(#2585) make this a by-move method on the arc +#[cfg(stage1)] +fn unwrap_mutex_arc<T: send>(+arc: mutex_arc<T>) -> 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<T: const send> &rw_arc<T> { } } +// FIXME(#2585) make this a by-move method on the arc +#[cfg(stage1)] +fn unwrap_rw_arc<T: const send>(+arc: rw_arc<T>) -> 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(); |
