Add unwrap for std::arc ARC variants
This commit is contained in:
@@ -6,8 +6,8 @@
|
|||||||
* between tasks.
|
* between tasks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import unsafe::{SharedMutableState,
|
import unsafe::{SharedMutableState, shared_mutable_state,
|
||||||
shared_mutable_state, clone_shared_mutable_state,
|
clone_shared_mutable_state, unwrap_shared_mutable_state,
|
||||||
get_shared_mutable_state, get_shared_immutable_state};
|
get_shared_mutable_state, get_shared_immutable_state};
|
||||||
import sync;
|
import sync;
|
||||||
import sync::{mutex, mutex_with_condvars, rwlock, rwlock_with_condvars};
|
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) } }
|
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)
|
* 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}.
|
// Common code for {mutex.access,rwlock.write}{,_cond}.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[doc(hidden)]
|
#[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
|
// Borrowck rightly complains about immutably aliasing the rwlock in order to
|
||||||
// lock it. This wraps the unsafety, with the justification that the 'lock'
|
// lock it. This wraps the unsafety, with the justification that the 'lock'
|
||||||
// field is never overwritten; only 'failed' and 'data'.
|
// field is never overwritten; only 'failed' and 'data'.
|
||||||
@@ -497,6 +527,22 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[test] #[should_fail] #[ignore(cfg(windows))]
|
#[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() {
|
fn test_rw_arc_poison_wr() {
|
||||||
let arc = ~rw_arc(1);
|
let arc = ~rw_arc(1);
|
||||||
let arc2 = ~arc.clone();
|
let arc2 = ~arc.clone();
|
||||||
|
|||||||
Reference in New Issue
Block a user