Skip to content

Commit bb0d9e5

Browse files
committed
---
yaml --- r: 23342 b: refs/heads/master c: 1aa50bb h: refs/heads/master v: v3
1 parent 58bf9ea commit bb0d9e5

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 05accaa16787285560c6ddb1afe9dec45726a7f4
2+
refs/heads/master: 1aa50bba7c11b8d3e2e66bd55913214fcb05a3cc
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: cd6f24f9d14ac90d167386a56e7a6ac1f0318195
55
refs/heads/try: ffbe0e0e00374358b789b0037bcb3a577cd218be

trunk/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)