@@ -192,35 +192,6 @@ impl<T:Send> MutexArc<T> {
192
192
MutexArc { x : UnsafeArc :: new ( data) }
193
193
}
194
194
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
- }
224
195
/**
225
196
* Access the underlying mutable data with mutual exclusion from other
226
197
* tasks. The argument closure will be run with the mutex locked; all
@@ -246,7 +217,14 @@ impl<T:Send> MutexArc<T> {
246
217
*/
247
218
#[ inline]
248
219
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
+ }
250
228
}
251
229
252
230
/// As unsafe_access(), but with a condvar, as sync::mutex.lock_cond().
@@ -255,7 +233,15 @@ impl<T:Send> MutexArc<T> {
255
233
blk : & fn ( x : & ' x mut T ,
256
234
c : & ' c Condvar ) -> U )
257
235
-> 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
+ }
259
245
}
260
246
261
247
/**
@@ -281,25 +267,30 @@ impl<T:Freeze + Send> MutexArc<T> {
281
267
* As unsafe_access.
282
268
*
283
269
* 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.
288
278
*
289
279
* Both methods have the same failure behaviour as unsafe_access and
290
280
* unsafe_access_cond.
291
281
*/
292
282
#[inline]
293
283
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) }
295
285
}
296
-
286
+
287
+ /// As unsafe_access_cond but safe and Freeze.
297
288
#[inline]
298
289
pub fn access_cond<'x, 'c, U>(&self,
299
290
blk: &fn(x: &'x mut T,
300
291
c: &'c Condvar) -> U)
301
292
-> U {
302
- unsafe { self.lock_and_access_cond (blk) }
293
+ unsafe { self.unsafe_access_cond (blk) }
303
294
}
304
295
}
305
296
@@ -707,7 +698,7 @@ mod tests {
707
698
let one = arc.unwrap();
708
699
assert!(one == 1);
709
700
}
710
-
701
+
711
702
#[test]
712
703
fn test_unsafe_mutex_arc_nested() {
713
704
unsafe {
@@ -722,90 +713,7 @@ mod tests {
722
713
}
723
714
}
724
715
};
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
- }
805
716
}
806
- let _ = p.recv();
807
- let one = arc.unwrap();
808
- assert!(one == 1);
809
717
}
810
718
811
719
#[test] #[should_fail]
0 commit comments