Skip to content

Commit a886549

Browse files
committed
auto merge of #12336 : kballard/rust/mutexarc-no-freeze, r=alexcrichton
With Rc no longer trying to statically prevent cycles (and thus no longer using the Freeze bound), it seems appropriate to remove that restriction from MutexArc as well. Closes #9251.
2 parents 54bccc5 + 449c34a commit a886549

File tree

2 files changed

+33
-98
lines changed

2 files changed

+33
-98
lines changed

src/libsync/arc.rs

+33-72
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,6 @@ impl<T:Send> MutexArc<T> {
192192
* other tasks wishing to access the data will block until the closure
193193
* finishes running.
194194
*
195-
* The reason this function is 'unsafe' is because it is possible to
196-
* construct a circular reference among multiple Arcs by mutating the
197-
* underlying data. This creates potential for deadlock, but worse, this
198-
* will guarantee a memory leak of all involved Arcs. Using MutexArcs
199-
* inside of other Arcs is safe in absence of circular references.
200-
*
201195
* If you wish to nest MutexArcs, one strategy for ensuring safety at
202196
* runtime is to add a "nesting level counter" inside the stored data, and
203197
* when traversing the arcs, assert that they monotonically decrease.
@@ -210,63 +204,33 @@ impl<T:Send> MutexArc<T> {
210204
* blocked on the mutex) will also fail immediately.
211205
*/
212206
#[inline]
213-
pub unsafe fn unsafe_access<U>(&self, blk: |x: &mut T| -> U) -> U {
207+
pub fn access<U>(&self, blk: |x: &mut T| -> U) -> U {
214208
let state = self.x.get();
215-
// Borrowck would complain about this if the function were
216-
// not already unsafe. See borrow_rwlock, far below.
217-
(&(*state).lock).lock(|| {
218-
check_poison(true, (*state).failed);
219-
let _z = PoisonOnFail::new(&mut (*state).failed);
220-
blk(&mut (*state).data)
221-
})
209+
unsafe {
210+
// Borrowck would complain about this if the code were
211+
// not already unsafe. See borrow_rwlock, far below.
212+
(&(*state).lock).lock(|| {
213+
check_poison(true, (*state).failed);
214+
let _z = PoisonOnFail::new(&mut (*state).failed);
215+
blk(&mut (*state).data)
216+
})
217+
}
222218
}
223219

224-
/// As unsafe_access(), but with a condvar, as sync::mutex.lock_cond().
220+
/// As access(), but with a condvar, as sync::mutex.lock_cond().
225221
#[inline]
226-
pub unsafe fn unsafe_access_cond<U>(&self,
227-
blk: |x: &mut T, c: &Condvar| -> U)
228-
-> U {
222+
pub fn access_cond<U>(&self, blk: |x: &mut T, c: &Condvar| -> U) -> U {
229223
let state = self.x.get();
230-
(&(*state).lock).lock_cond(|cond| {
231-
check_poison(true, (*state).failed);
232-
let _z = PoisonOnFail::new(&mut (*state).failed);
233-
blk(&mut (*state).data,
234-
&Condvar {is_mutex: true,
235-
failed: &(*state).failed,
236-
cond: cond })
237-
})
238-
}
239-
}
240-
241-
impl<T:Freeze + Send> MutexArc<T> {
242-
243-
/**
244-
* As unsafe_access.
245-
*
246-
* The difference between access and unsafe_access is that the former
247-
* forbids mutexes to be nested. While unsafe_access can be used on
248-
* MutexArcs without freezable interiors, this safe version of access
249-
* requires the Freeze bound, which prohibits access on MutexArcs which
250-
* might contain nested MutexArcs inside.
251-
*
252-
* The purpose of this is to offer a safe implementation of MutexArc to be
253-
* used instead of RWArc in cases where no readers are needed and slightly
254-
* better performance is required.
255-
*
256-
* Both methods have the same failure behaviour as unsafe_access and
257-
* unsafe_access_cond.
258-
*/
259-
#[inline]
260-
pub fn access<U>(&self, blk: |x: &mut T| -> U) -> U {
261-
unsafe { self.unsafe_access(blk) }
262-
}
263-
264-
/// As unsafe_access_cond but safe and Freeze.
265-
#[inline]
266-
pub fn access_cond<U>(&self,
267-
blk: |x: &mut T, c: &Condvar| -> U)
268-
-> U {
269-
unsafe { self.unsafe_access_cond(blk) }
224+
unsafe {
225+
(&(*state).lock).lock_cond(|cond| {
226+
check_poison(true, (*state).failed);
227+
let _z = PoisonOnFail::new(&mut (*state).failed);
228+
blk(&mut (*state).data,
229+
&Condvar {is_mutex: true,
230+
failed: &(*state).failed,
231+
cond: cond })
232+
})
233+
}
270234
}
271235
}
272236

@@ -590,7 +554,6 @@ impl<T:Clone+Send+Freeze> CowArc<T> {
590554

591555
impl<T:Clone+Send+Freeze> Clone for CowArc<T> {
592556
/// Duplicate a Copy-on-write Arc. See arc::clone for more details.
593-
#[inline]
594557
fn clone(&self) -> CowArc<T> {
595558
CowArc { x: self.x.clone() }
596559
}
@@ -692,20 +655,18 @@ mod tests {
692655
}
693656

694657
#[test]
695-
fn test_unsafe_mutex_arc_nested() {
696-
unsafe {
697-
// Tests nested mutexes and access
698-
// to underlaying data.
699-
let arc = ~MutexArc::new(1);
700-
let arc2 = ~MutexArc::new(*arc);
701-
task::spawn(proc() {
702-
(*arc2).unsafe_access(|mutex| {
703-
(*mutex).access(|one| {
704-
assert!(*one == 1);
705-
})
658+
fn test_mutex_arc_nested() {
659+
// Tests nested mutexes and access
660+
// to underlaying data.
661+
let arc = ~MutexArc::new(1);
662+
let arc2 = ~MutexArc::new(*arc);
663+
task::spawn(proc() {
664+
(*arc2).access(|mutex| {
665+
(*mutex).access(|one| {
666+
assert!(*one == 1);
706667
})
707-
});
708-
}
668+
})
669+
});
709670
}
710671

711672
#[test]

src/test/compile-fail/mutex-arc-nested.rs

-26
This file was deleted.

0 commit comments

Comments
 (0)