@@ -133,7 +133,7 @@ impl<'a, T: ?Sized> !marker::Send for RwLockReadGuard<'a, T> {}
133133#[ stable( feature = "rust1" , since = "1.0.0" ) ]
134134pub struct RwLockWriteGuard < ' a , T : ?Sized + ' a > {
135135 __lock : & ' a StaticRwLock ,
136- __data : & ' a UnsafeCell < T > ,
136+ __data : & ' a mut T ,
137137 __poison : poison:: Guard ,
138138}
139139
@@ -178,7 +178,7 @@ impl<T: ?Sized> RwLock<T> {
178178 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
179179 pub fn read ( & self ) -> LockResult < RwLockReadGuard < T > > {
180180 unsafe { self . inner . lock . read ( ) }
181- RwLockReadGuard :: new ( & * self . inner , & self . data )
181+ unsafe { RwLockReadGuard :: new ( & * self . inner , & self . data ) }
182182 }
183183
184184 /// Attempts to acquire this rwlock with shared read access.
@@ -202,7 +202,7 @@ impl<T: ?Sized> RwLock<T> {
202202 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
203203 pub fn try_read ( & self ) -> TryLockResult < RwLockReadGuard < T > > {
204204 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 ) } ) )
206206 } else {
207207 Err ( TryLockError :: WouldBlock )
208208 }
@@ -226,7 +226,7 @@ impl<T: ?Sized> RwLock<T> {
226226 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
227227 pub fn write ( & self ) -> LockResult < RwLockWriteGuard < T > > {
228228 unsafe { self . inner . lock . write ( ) }
229- RwLockWriteGuard :: new ( & * self . inner , & self . data )
229+ unsafe { RwLockWriteGuard :: new ( & * self . inner , & self . data ) }
230230 }
231231
232232 /// Attempts to lock this rwlock with exclusive write access.
@@ -250,7 +250,7 @@ impl<T: ?Sized> RwLock<T> {
250250 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
251251 pub fn try_write ( & self ) -> TryLockResult < RwLockWriteGuard < T > > {
252252 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 ) } ) )
254254 } else {
255255 Err ( TryLockError :: WouldBlock )
256256 }
@@ -361,7 +361,7 @@ impl StaticRwLock {
361361 #[ inline]
362362 pub fn read ( & ' static self ) -> LockResult < RwLockReadGuard < ' static , ( ) > > {
363363 unsafe { self . lock . read ( ) }
364- RwLockReadGuard :: new ( self , & DUMMY . 0 )
364+ unsafe { RwLockReadGuard :: new ( self , & DUMMY . 0 ) }
365365 }
366366
367367 /// Attempts to acquire this lock with shared read access.
@@ -371,7 +371,7 @@ impl StaticRwLock {
371371 pub fn try_read ( & ' static self )
372372 -> TryLockResult < RwLockReadGuard < ' static , ( ) > > {
373373 if unsafe { self . lock . try_read ( ) } {
374- Ok ( try!( RwLockReadGuard :: new ( self , & DUMMY . 0 ) ) )
374+ unsafe { Ok ( try!( RwLockReadGuard :: new ( self , & DUMMY . 0 ) ) ) }
375375 } else {
376376 Err ( TryLockError :: WouldBlock )
377377 }
@@ -384,7 +384,7 @@ impl StaticRwLock {
384384 #[ inline]
385385 pub fn write ( & ' static self ) -> LockResult < RwLockWriteGuard < ' static , ( ) > > {
386386 unsafe { self . lock . write ( ) }
387- RwLockWriteGuard :: new ( self , & DUMMY . 0 )
387+ unsafe { RwLockWriteGuard :: new ( self , & DUMMY . 0 ) }
388388 }
389389
390390 /// Attempts to lock this rwlock with exclusive write access.
@@ -394,7 +394,7 @@ impl StaticRwLock {
394394 pub fn try_write ( & ' static self )
395395 -> TryLockResult < RwLockWriteGuard < ' static , ( ) > > {
396396 if unsafe { self . lock . try_write ( ) } {
397- Ok ( try!( RwLockWriteGuard :: new ( self , & DUMMY . 0 ) ) )
397+ Ok ( unsafe { try!( RwLockWriteGuard :: new ( self , & DUMMY . 0 ) ) } )
398398 } else {
399399 Err ( TryLockError :: WouldBlock )
400400 }
@@ -412,12 +412,12 @@ impl StaticRwLock {
412412}
413413
414414impl < ' 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 > )
416416 -> LockResult < RwLockReadGuard < ' rwlock , T > > {
417417 poison:: map_result ( lock. poison . borrow ( ) , |_| {
418418 RwLockReadGuard {
419419 __lock : lock,
420- __data : unsafe { & * data. get ( ) } ,
420+ __data : & * data. get ( ) ,
421421 }
422422 } )
423423 }
@@ -427,7 +427,10 @@ impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
427427 /// Applies the supplied closure to the data, returning a new lock
428428 /// guard referencing the borrow returned by the closure.
429429 ///
430+ /// # Examples
431+ ///
430432 /// ```rust
433+ /// # #![feature(guard_map)]
431434 /// # use std::sync::{RwLockReadGuard, RwLock};
432435 /// let x = RwLock::new(vec![1, 2]);
433436 ///
@@ -451,12 +454,12 @@ impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
451454}
452455
453456impl < ' 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 > )
455458 -> LockResult < RwLockWriteGuard < ' rwlock , T > > {
456459 poison:: map_result ( lock. poison . borrow ( ) , |guard| {
457460 RwLockWriteGuard {
458461 __lock : lock,
459- __data : data,
462+ __data : & mut * data. get ( ) ,
460463 __poison : guard,
461464 }
462465 } )
@@ -467,7 +470,10 @@ impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
467470 /// Applies the supplied closure to the data, returning a new lock
468471 /// guard referencing the borrow returned by the closure.
469472 ///
473+ /// # Examples
474+ ///
470475 /// ```rust
476+ /// # #![feature(guard_map)]
471477 /// # use std::sync::{RwLockWriteGuard, RwLock};
472478 /// let x = RwLock::new(vec![1, 2]);
473479 ///
@@ -485,11 +491,13 @@ impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
485491 issue = "0" ) ]
486492 pub fn map < U : ?Sized , F > ( this : Self , cb : F ) -> RwLockWriteGuard < ' rwlock , U >
487493 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 ) ;
492498
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.
493501 let poison = unsafe { ptr:: read ( & this. __poison ) } ;
494502 let lock = unsafe { ptr:: read ( & this. __lock ) } ;
495503 mem:: forget ( this) ;
@@ -513,13 +521,12 @@ impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> {
513521impl < ' rwlock , T : ?Sized > Deref for RwLockWriteGuard < ' rwlock , T > {
514522 type Target = T ;
515523
516- fn deref ( & self ) -> & T { unsafe { & * self . __data . get ( ) } }
524+ fn deref ( & self ) -> & T { self . __data }
517525}
518526
519527#[ stable( feature = "rust1" , since = "1.0.0" ) ]
520528impl < ' 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
523530 }
524531}
525532
0 commit comments