@@ -133,7 +133,7 @@ impl<'a, T: ?Sized> !marker::Send for RwLockReadGuard<'a, T> {}
133
133
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
134
134
pub struct RwLockWriteGuard < ' a , T : ?Sized + ' a > {
135
135
__lock : & ' a StaticRwLock ,
136
- __data : & ' a UnsafeCell < T > ,
136
+ __data : & ' a mut T ,
137
137
__poison : poison:: Guard ,
138
138
}
139
139
@@ -178,7 +178,7 @@ impl<T: ?Sized> RwLock<T> {
178
178
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
179
179
pub fn read ( & self ) -> LockResult < RwLockReadGuard < T > > {
180
180
unsafe { self . inner . lock . read ( ) }
181
- RwLockReadGuard :: new ( & * self . inner , & self . data )
181
+ unsafe { RwLockReadGuard :: new ( & * self . inner , & self . data ) }
182
182
}
183
183
184
184
/// Attempts to acquire this rwlock with shared read access.
@@ -202,7 +202,7 @@ impl<T: ?Sized> RwLock<T> {
202
202
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
203
203
pub fn try_read ( & self ) -> TryLockResult < RwLockReadGuard < T > > {
204
204
if unsafe { self . inner . lock . try_read ( ) } {
205
- Ok ( try!( RwLockReadGuard :: new ( & * self . inner , & self . data ) ) )
205
+ Ok ( try!( unsafe { RwLockReadGuard :: new ( & * self . inner , & self . data ) } ) )
206
206
} else {
207
207
Err ( TryLockError :: WouldBlock )
208
208
}
@@ -226,7 +226,7 @@ impl<T: ?Sized> RwLock<T> {
226
226
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
227
227
pub fn write ( & self ) -> LockResult < RwLockWriteGuard < T > > {
228
228
unsafe { self . inner . lock . write ( ) }
229
- RwLockWriteGuard :: new ( & * self . inner , & self . data )
229
+ unsafe { RwLockWriteGuard :: new ( & * self . inner , & self . data ) }
230
230
}
231
231
232
232
/// Attempts to lock this rwlock with exclusive write access.
@@ -250,7 +250,7 @@ impl<T: ?Sized> RwLock<T> {
250
250
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
251
251
pub fn try_write ( & self ) -> TryLockResult < RwLockWriteGuard < T > > {
252
252
if unsafe { self . inner . lock . try_write ( ) } {
253
- Ok ( try!( RwLockWriteGuard :: new ( & * self . inner , & self . data ) ) )
253
+ Ok ( try!( unsafe { RwLockWriteGuard :: new ( & * self . inner , & self . data ) } ) )
254
254
} else {
255
255
Err ( TryLockError :: WouldBlock )
256
256
}
@@ -361,7 +361,7 @@ impl StaticRwLock {
361
361
#[ inline]
362
362
pub fn read ( & ' static self ) -> LockResult < RwLockReadGuard < ' static , ( ) > > {
363
363
unsafe { self . lock . read ( ) }
364
- RwLockReadGuard :: new ( self , & DUMMY . 0 )
364
+ unsafe { RwLockReadGuard :: new ( self , & DUMMY . 0 ) }
365
365
}
366
366
367
367
/// Attempts to acquire this lock with shared read access.
@@ -371,7 +371,7 @@ impl StaticRwLock {
371
371
pub fn try_read ( & ' static self )
372
372
-> TryLockResult < RwLockReadGuard < ' static , ( ) > > {
373
373
if unsafe { self . lock . try_read ( ) } {
374
- Ok ( try!( RwLockReadGuard :: new ( self , & DUMMY . 0 ) ) )
374
+ unsafe { Ok ( try!( RwLockReadGuard :: new ( self , & DUMMY . 0 ) ) ) }
375
375
} else {
376
376
Err ( TryLockError :: WouldBlock )
377
377
}
@@ -384,7 +384,7 @@ impl StaticRwLock {
384
384
#[ inline]
385
385
pub fn write ( & ' static self ) -> LockResult < RwLockWriteGuard < ' static , ( ) > > {
386
386
unsafe { self . lock . write ( ) }
387
- RwLockWriteGuard :: new ( self , & DUMMY . 0 )
387
+ unsafe { RwLockWriteGuard :: new ( self , & DUMMY . 0 ) }
388
388
}
389
389
390
390
/// Attempts to lock this rwlock with exclusive write access.
@@ -394,7 +394,7 @@ impl StaticRwLock {
394
394
pub fn try_write ( & ' static self )
395
395
-> TryLockResult < RwLockWriteGuard < ' static , ( ) > > {
396
396
if unsafe { self . lock . try_write ( ) } {
397
- Ok ( try!( RwLockWriteGuard :: new ( self , & DUMMY . 0 ) ) )
397
+ Ok ( unsafe { try!( RwLockWriteGuard :: new ( self , & DUMMY . 0 ) ) } )
398
398
} else {
399
399
Err ( TryLockError :: WouldBlock )
400
400
}
@@ -412,12 +412,12 @@ impl StaticRwLock {
412
412
}
413
413
414
414
impl < ' rwlock , T : ?Sized > RwLockReadGuard < ' rwlock , T > {
415
- fn new ( lock : & ' rwlock StaticRwLock , data : & ' rwlock UnsafeCell < T > )
415
+ unsafe fn new ( lock : & ' rwlock StaticRwLock , data : & ' rwlock UnsafeCell < T > )
416
416
-> LockResult < RwLockReadGuard < ' rwlock , T > > {
417
417
poison:: map_result ( lock. poison . borrow ( ) , |_| {
418
418
RwLockReadGuard {
419
419
__lock : lock,
420
- __data : unsafe { & * data. get ( ) } ,
420
+ __data : & * data. get ( ) ,
421
421
}
422
422
} )
423
423
}
@@ -427,7 +427,10 @@ impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
427
427
/// Applies the supplied closure to the data, returning a new lock
428
428
/// guard referencing the borrow returned by the closure.
429
429
///
430
+ /// # Examples
431
+ ///
430
432
/// ```rust
433
+ /// # #![feature(guard_map)]
431
434
/// # use std::sync::{RwLockReadGuard, RwLock};
432
435
/// let x = RwLock::new(vec![1, 2]);
433
436
///
@@ -451,12 +454,12 @@ impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
451
454
}
452
455
453
456
impl < ' rwlock , T : ?Sized > RwLockWriteGuard < ' rwlock , T > {
454
- fn new ( lock : & ' rwlock StaticRwLock , data : & ' rwlock UnsafeCell < T > )
457
+ unsafe fn new ( lock : & ' rwlock StaticRwLock , data : & ' rwlock UnsafeCell < T > )
455
458
-> LockResult < RwLockWriteGuard < ' rwlock , T > > {
456
459
poison:: map_result ( lock. poison . borrow ( ) , |guard| {
457
460
RwLockWriteGuard {
458
461
__lock : lock,
459
- __data : data,
462
+ __data : & mut * data. get ( ) ,
460
463
__poison : guard,
461
464
}
462
465
} )
@@ -467,7 +470,10 @@ impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
467
470
/// Applies the supplied closure to the data, returning a new lock
468
471
/// guard referencing the borrow returned by the closure.
469
472
///
473
+ /// # Examples
474
+ ///
470
475
/// ```rust
476
+ /// # #![feature(guard_map)]
471
477
/// # use std::sync::{RwLockWriteGuard, RwLock};
472
478
/// let x = RwLock::new(vec![1, 2]);
473
479
///
@@ -485,11 +491,13 @@ impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
485
491
issue = "0" ) ]
486
492
pub fn map < U : ?Sized , F > ( this : Self , cb : F ) -> RwLockWriteGuard < ' rwlock , U >
487
493
where F : FnOnce ( & ' rwlock mut T ) -> & ' rwlock mut U {
488
- let new_data = unsafe {
489
- let data : & ' rwlock mut T = & mut * this . __data . get ( ) ;
490
- mem :: transmute :: < & ' rwlock mut U , & ' rwlock UnsafeCell < U > > ( cb ( data ) )
491
- } ;
494
+ // Compute the new data while still owning the original lock
495
+ // in order to correctly poison if the callback panics.
496
+ let data = unsafe { ptr :: read ( & this . __data ) } ;
497
+ let new_data = cb ( data ) ;
492
498
499
+ // We don't want to unlock the lock by running the destructor of the
500
+ // original lock, so just read the fields we need and forget it.
493
501
let poison = unsafe { ptr:: read ( & this. __poison ) } ;
494
502
let lock = unsafe { ptr:: read ( & this. __lock ) } ;
495
503
mem:: forget ( this) ;
@@ -513,13 +521,12 @@ impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> {
513
521
impl < ' rwlock , T : ?Sized > Deref for RwLockWriteGuard < ' rwlock , T > {
514
522
type Target = T ;
515
523
516
- fn deref ( & self ) -> & T { unsafe { & * self . __data . get ( ) } }
524
+ fn deref ( & self ) -> & T { self . __data }
517
525
}
518
526
519
527
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
520
528
impl < ' rwlock , T : ?Sized > DerefMut for RwLockWriteGuard < ' rwlock , T > {
521
- fn deref_mut ( & mut self ) -> & mut T {
522
- unsafe { & mut * self . __data . get ( ) }
529
+ fn deref_mut ( & mut self ) -> & mut T { self . __data
523
530
}
524
531
}
525
532
0 commit comments