|
6 | 6 | * between tasks.
|
7 | 7 | */
|
8 | 8 |
|
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, |
11 | 11 | get_shared_mutable_state, get_shared_immutable_state};
|
12 | 12 | import sync;
|
13 | 13 | import sync::{mutex, mutex_with_condvars, rwlock, rwlock_with_condvars};
|
@@ -93,6 +93,12 @@ fn clone<T: const send>(rc: &arc<T>) -> arc<T> {
|
93 | 93 | arc { x: unsafe { clone_shared_mutable_state(&rc.x) } }
|
94 | 94 | }
|
95 | 95 |
|
| 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 | + |
96 | 102 | /****************************************************************************
|
97 | 103 | * Mutex protected ARC (unsafe)
|
98 | 104 | ****************************************************************************/
|
@@ -181,6 +187,18 @@ impl<T: send> &mutex_arc<T> {
|
181 | 187 | }
|
182 | 188 | }
|
183 | 189 |
|
| 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 | +
|
184 | 202 | // Common code for {mutex.access,rwlock.write}{,_cond}.
|
185 | 203 | #[inline(always)]
|
186 | 204 | #[doc(hidden)]
|
@@ -347,6 +365,18 @@ impl<T: const send> &rw_arc<T> {
|
347 | 365 | }
|
348 | 366 | }
|
349 | 367 |
|
| 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 | +
|
350 | 380 | // Borrowck rightly complains about immutably aliasing the rwlock in order to
|
351 | 381 | // lock it. This wraps the unsafety, with the justification that the 'lock'
|
352 | 382 | // field is never overwritten; only 'failed' and 'data'.
|
@@ -497,6 +527,22 @@ mod tests {
|
497 | 527 | }
|
498 | 528 | }
|
499 | 529 | #[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))] |
500 | 546 | fn test_rw_arc_poison_wr() {
|
501 | 547 | let arc = ~rw_arc(1);
|
502 | 548 | let arc2 = ~arc.clone();
|
|
0 commit comments