Skip to content

Commit 1aa50bb

Browse files
committed
Add unwrap for std::arc ARC variants
1 parent 05accaa commit 1aa50bb

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

src/libstd/arc.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
* between tasks.
77
*/
88

9-
import unsafe::{SharedMutableState,
10-
shared_mutable_state, clone_shared_mutable_state,
9+
import unsafe::{SharedMutableState, shared_mutable_state,
10+
clone_shared_mutable_state, unwrap_shared_mutable_state,
1111
get_shared_mutable_state, get_shared_immutable_state};
1212
import sync;
1313
import sync::{mutex, mutex_with_condvars, rwlock, rwlock_with_condvars};
@@ -93,6 +93,12 @@ fn clone<T: const send>(rc: &arc<T>) -> arc<T> {
9393
arc { x: unsafe { clone_shared_mutable_state(&rc.x) } }
9494
}
9595

96+
#[cfg(stage1)]
97+
fn unwrap<T: const send>(+rc: arc<T>) -> T {
98+
let arc { x: x } = rc;
99+
unsafe { unwrap_shared_mutable_state(x) }
100+
}
101+
96102
/****************************************************************************
97103
* Mutex protected ARC (unsafe)
98104
****************************************************************************/
@@ -181,6 +187,18 @@ impl<T: send> &mutex_arc<T> {
181187
}
182188
}
183189

190+
// FIXME(#2585) make this a by-move method on the arc
191+
#[cfg(stage1)]
192+
fn unwrap_mutex_arc<T: send>(+arc: mutex_arc<T>) -> T {
193+
let mutex_arc { x: x } = arc;
194+
let inner = unsafe { unwrap_shared_mutable_state(x) };
195+
let mutex_arc_inner { failed: failed, data: data, _ } = inner;
196+
if failed {
197+
fail ~"Can't unwrap poisoned mutex_arc - another task failed inside!"
198+
}
199+
data
200+
}
201+
184202
// Common code for {mutex.access,rwlock.write}{,_cond}.
185203
#[inline(always)]
186204
#[doc(hidden)]
@@ -347,6 +365,18 @@ impl<T: const send> &rw_arc<T> {
347365
}
348366
}
349367
368+
// FIXME(#2585) make this a by-move method on the arc
369+
#[cfg(stage1)]
370+
fn unwrap_rw_arc<T: const send>(+arc: rw_arc<T>) -> T {
371+
let rw_arc { x: x, _ } = arc;
372+
let inner = unsafe { unwrap_shared_mutable_state(x) };
373+
let rw_arc_inner { failed: failed, data: data, _ } = inner;
374+
if failed {
375+
fail ~"Can't unwrap poisoned rw_arc - another task failed inside!"
376+
}
377+
data
378+
}
379+
350380
// Borrowck rightly complains about immutably aliasing the rwlock in order to
351381
// lock it. This wraps the unsafety, with the justification that the 'lock'
352382
// field is never overwritten; only 'failed' and 'data'.
@@ -497,6 +527,22 @@ mod tests {
497527
}
498528
}
499529
#[test] #[should_fail] #[ignore(cfg(windows))]
530+
#[cfg(stage1)]
531+
fn test_mutex_arc_unwrap_poison() {
532+
let arc = mutex_arc(1);
533+
let arc2 = ~(&arc).clone();
534+
let (c,p) = pipes::stream();
535+
do task::spawn {
536+
do arc2.access |one| {
537+
c.send(());
538+
assert *one == 2;
539+
}
540+
}
541+
let _ = p.recv();
542+
let one = unwrap_mutex_arc(arc);
543+
assert one == 1;
544+
}
545+
#[test] #[should_fail] #[ignore(cfg(windows))]
500546
fn test_rw_arc_poison_wr() {
501547
let arc = ~rw_arc(1);
502548
let arc2 = ~arc.clone();

0 commit comments

Comments
 (0)