@@ -192,35 +192,6 @@ impl<T:Send> MutexArc<T> {
192192 MutexArc { x : UnsafeArc :: new ( data) }
193193 }
194194
195-
196- /// Refer unsafe_access and access methods for the documentaiton.
197- #[ inline]
198- unsafe fn lock_and_access < U > ( & self , blk : & fn ( x : & mut T ) -> U ) -> U {
199- let state = self . x . get ( ) ;
200- // Borrowck would complain about this if the function were
201- // not already unsafe. See borrow_rwlock, far below.
202- do ( & ( * state) . lock ) . lock {
203- check_poison ( true , ( * state) . failed ) ;
204- let _z = PoisonOnFail ( & mut ( * state) . failed ) ;
205- blk ( & mut ( * state) . data )
206- }
207- }
208-
209- #[ inline]
210- unsafe fn lock_and_access_cond < ' x , ' c , U > ( & self ,
211- blk : & fn ( x : & ' x mut T ,
212- c : & ' c Condvar ) -> U )
213- -> U {
214- let state = self . x . get ( ) ;
215- do ( & ( * state) . lock ) . lock_cond |cond| {
216- check_poison ( true , ( * state) . failed ) ;
217- let _z = PoisonOnFail ( & mut ( * state) . failed ) ;
218- blk ( & mut ( * state) . data ,
219- & Condvar { is_mutex : true ,
220- failed : & mut ( * state) . failed ,
221- cond : cond } )
222- }
223- }
224195 /**
225196 * Access the underlying mutable data with mutual exclusion from other
226197 * tasks. The argument closure will be run with the mutex locked; all
@@ -246,7 +217,14 @@ impl<T:Send> MutexArc<T> {
246217 */
247218 #[ inline]
248219 pub unsafe fn unsafe_access < U > ( & self , blk : & fn ( x : & mut T ) -> U ) -> U {
249- self . lock_and_access ( blk)
220+ let state = self . x . get ( ) ;
221+ // Borrowck would complain about this if the function were
222+ // not already unsafe. See borrow_rwlock, far below.
223+ do ( & ( * state) . lock ) . lock {
224+ check_poison ( true , ( * state) . failed ) ;
225+ let _z = PoisonOnFail ( & mut ( * state) . failed ) ;
226+ blk ( & mut ( * state) . data )
227+ }
250228 }
251229
252230 /// As unsafe_access(), but with a condvar, as sync::mutex.lock_cond().
@@ -255,7 +233,15 @@ impl<T:Send> MutexArc<T> {
255233 blk : & fn ( x : & ' x mut T ,
256234 c : & ' c Condvar ) -> U )
257235 -> U {
258- self . lock_and_access_cond ( blk)
236+ let state = self . x . get ( ) ;
237+ do ( & ( * state) . lock ) . lock_cond |cond| {
238+ check_poison ( true , ( * state) . failed ) ;
239+ let _z = PoisonOnFail ( & mut ( * state) . failed ) ;
240+ blk ( & mut ( * state) . data ,
241+ & Condvar { is_mutex : true ,
242+ failed : & mut ( * state) . failed ,
243+ cond : cond } )
244+ }
259245 }
260246
261247 /**
@@ -281,25 +267,30 @@ impl<T:Freeze + Send> MutexArc<T> {
281267 * As unsafe_access.
282268 *
283269 * The difference between access and unsafe_access is that the former
284- * forbids mutexes to be nested. The purpose of this is to offer a safe
285- * implementation of both methods access and access_cond to be used instead
286- * of rwlock in cases where no readers are needed and sightly better performance
287- * is required.
270+ * forbids mutexes to be nested. While unsafe_access can be used on
271+ * MutexArcs without freezable interiors, this safe version of access
272+ * requires the Freeze bound, which prohibits access on MutexArcs which
273+ * might contain nested MutexArcs inside.
274+ *
275+ * The purpose of this is to offer a safe implementation of both methods
276+ * access and access_cond to be used instead of rwlock in cases where no
277+ * readers are needed and sightly better performance is required.
288278 *
289279 * Both methods have the same failure behaviour as unsafe_access and
290280 * unsafe_access_cond.
291281 */
292282 #[inline]
293283 pub fn access<U>(&self, blk: &fn(x: &mut T) -> U) -> U {
294- unsafe { self.lock_and_access (blk) }
284+ unsafe { self.unsafe_access (blk) }
295285 }
296-
286+
287+ /// As unsafe_access_cond but safe and Freeze.
297288 #[inline]
298289 pub fn access_cond<'x, 'c, U>(&self,
299290 blk: &fn(x: &'x mut T,
300291 c: &'c Condvar) -> U)
301292 -> U {
302- unsafe { self.lock_and_access_cond (blk) }
293+ unsafe { self.unsafe_access_cond (blk) }
303294 }
304295}
305296
@@ -707,7 +698,7 @@ mod tests {
707698 let one = arc.unwrap();
708699 assert!(one == 1);
709700 }
710-
701+
711702 #[test]
712703 fn test_unsafe_mutex_arc_nested() {
713704 unsafe {
@@ -722,90 +713,7 @@ mod tests {
722713 }
723714 }
724715 };
725- }
726- }
727-
728- #[test]
729- fn test_unsafe_mutex_arc_condvar() {
730- unsafe {
731- let arc = MutexArc::new(false);
732- let arc2 = arc.clone();
733- let (p, c) = comm::oneshot();
734- let (c, p) = (Cell::new(c), Cell::new(p));
735- do task::spawn {
736- // wait until parent gets in
737- p.take().recv();
738- do arc2.unsafe_access_cond |state, cond| {
739- *state = true;
740- cond.signal();
741- }
742- }
743- do arc.unsafe_access_cond |state, cond| {
744- c.take().send(());
745- assert!(!*state);
746- while !*state {
747- cond.wait();
748- }
749- }
750- }
751- }
752-
753- #[test] #[should_fail]
754- fn test_unsafe_arc_condvar_poison() {
755- unsafe {
756- let arc = MutexArc::new(1);
757- let arc2 = arc.clone();
758- let (p, c) = comm::stream();
759-
760- do task::spawn_unlinked {
761- let _ = p.recv();
762- do arc2.unsafe_access_cond |one, cond| {
763- cond.signal();
764- // Parent should fail when it wakes up.
765- assert_eq!(*one, 0);
766- }
767- }
768-
769- do arc.unsafe_access_cond |one, cond| {
770- c.send(());
771- while *one == 1 {
772- cond.wait();
773- }
774- }
775- }
776- }
777- #[test] #[should_fail]
778- fn test_unsafe_mutex_arc_poison() {
779- unsafe {
780- let arc = MutexArc::new(1);
781- let arc2 = arc.clone();
782- do task::try {
783- do arc2.unsafe_access |one| {
784- assert_eq!(*one, 2);
785- }
786- };
787- do arc.unsafe_access |one| {
788- assert_eq!(*one, 1);
789- }
790- }
791- }
792-
793- #[test] #[should_fail]
794- pub fn test_unsafe_mutex_arc_unwrap_poison() {
795- let arc = MutexArc::new(1);
796- let arc2 = arc.clone();
797- let (p, c) = comm::stream();
798- do task::spawn {
799- unsafe {
800- do arc2.unsafe_access |one| {
801- c.send(());
802- assert!(*one == 2);
803- }
804- }
805716 }
806- let _ = p.recv();
807- let one = arc.unwrap();
808- assert!(one == 1);
809717 }
810718
811719 #[test] #[should_fail]
0 commit comments