1- use std:: cell:: UnsafeCell ;
1+ use async_rwlock:: {
2+ RwLock as RawRwLock , RwLockReadGuard as RawRwLockReadGuard ,
3+ RwLockWriteGuard as RawRwLockWriteGuard ,
4+ } ;
5+
26use std:: fmt;
3- use std:: isize;
47use std:: ops:: { Deref , DerefMut } ;
5- use std:: pin:: Pin ;
6- use std:: process;
7- use std:: future:: Future ;
8- use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
9-
10- use crate :: sync:: WakerSet ;
11- use crate :: task:: { Context , Poll } ;
12-
13- /// Set if a write lock is held.
14- #[ allow( clippy:: identity_op) ]
15- const WRITE_LOCK : usize = 1 << 0 ;
16-
17- /// The value of a single blocked read contributing to the read count.
18- const ONE_READ : usize = 1 << 1 ;
19-
20- /// The bits in which the read count is stored.
21- const READ_COUNT_MASK : usize = !( ONE_READ - 1 ) ;
8+ use std:: sync:: atomic:: Ordering ;
229
2310/// A reader-writer lock for protecting shared data.
2411///
@@ -50,10 +37,7 @@ const READ_COUNT_MASK: usize = !(ONE_READ - 1);
5037/// # })
5138/// ```
5239pub struct RwLock < T : ?Sized > {
53- state : AtomicUsize ,
54- read_wakers : WakerSet ,
55- write_wakers : WakerSet ,
56- value : UnsafeCell < T > ,
40+ inner : RawRwLock < T > ,
5741}
5842
5943unsafe impl < T : ?Sized + Send > Send for RwLock < T > { }
@@ -70,11 +54,8 @@ impl<T> RwLock<T> {
7054 /// let lock = RwLock::new(0);
7155 /// ```
7256 pub fn new ( t : T ) -> RwLock < T > {
73- RwLock {
74- state : AtomicUsize :: new ( 0 ) ,
75- read_wakers : WakerSet :: new ( ) ,
76- write_wakers : WakerSet :: new ( ) ,
77- value : UnsafeCell :: new ( t) ,
57+ Self {
58+ inner : RawRwLock :: new ( t) ,
7859 }
7960 }
8061}
@@ -101,58 +82,7 @@ impl<T: ?Sized> RwLock<T> {
10182 /// # })
10283 /// ```
10384 pub async fn read ( & self ) -> RwLockReadGuard < ' _ , T > {
104- pub struct ReadFuture < ' a , T : ?Sized > {
105- lock : & ' a RwLock < T > ,
106- opt_key : Option < usize > ,
107- }
108-
109- impl < ' a , T : ?Sized > Future for ReadFuture < ' a , T > {
110- type Output = RwLockReadGuard < ' a , T > ;
111-
112- fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
113- loop {
114- // If the current task is in the set, remove it.
115- if let Some ( key) = self . opt_key . take ( ) {
116- self . lock . read_wakers . remove ( key) ;
117- }
118-
119- // Try acquiring a read lock.
120- match self . lock . try_read ( ) {
121- Some ( guard) => return Poll :: Ready ( guard) ,
122- None => {
123- // Insert this lock operation.
124- self . opt_key = Some ( self . lock . read_wakers . insert ( cx) ) ;
125-
126- // If the lock is still acquired for writing, return.
127- if self . lock . state . load ( Ordering :: SeqCst ) & WRITE_LOCK != 0 {
128- return Poll :: Pending ;
129- }
130- }
131- }
132- }
133- }
134- }
135-
136- impl < T : ?Sized > Drop for ReadFuture < ' _ , T > {
137- fn drop ( & mut self ) {
138- // If the current task is still in the set, that means it is being cancelled now.
139- if let Some ( key) = self . opt_key {
140- self . lock . read_wakers . cancel ( key) ;
141-
142- // If there are no active readers, notify a blocked writer if none were
143- // notified already.
144- if self . lock . state . load ( Ordering :: SeqCst ) & READ_COUNT_MASK == 0 {
145- self . lock . write_wakers . notify_any ( ) ;
146- }
147- }
148- }
149- }
150-
151- ReadFuture {
152- lock : self ,
153- opt_key : None ,
154- }
155- . await
85+ self . inner . read ( )
15686 }
15787
15888 /// Attempts to acquire a read lock.
@@ -179,30 +109,7 @@ impl<T: ?Sized> RwLock<T> {
179109 /// # })
180110 /// ```
181111 pub fn try_read ( & self ) -> Option < RwLockReadGuard < ' _ , T > > {
182- let mut state = self . state . load ( Ordering :: SeqCst ) ;
183-
184- loop {
185- // If a write lock is currently held, then a read lock cannot be acquired.
186- if state & WRITE_LOCK != 0 {
187- return None ;
188- }
189-
190- // Make sure the number of readers doesn't overflow.
191- if state > isize:: MAX as usize {
192- process:: abort ( ) ;
193- }
194-
195- // Increment the number of active reads.
196- match self . state . compare_exchange_weak (
197- state,
198- state + ONE_READ ,
199- Ordering :: SeqCst ,
200- Ordering :: SeqCst ,
201- ) {
202- Ok ( _) => return Some ( RwLockReadGuard ( self ) ) ,
203- Err ( s) => state = s,
204- }
205- }
112+ self . inner . try_read ( )
206113 }
207114
208115 /// Acquires a write lock.
@@ -226,55 +133,7 @@ impl<T: ?Sized> RwLock<T> {
226133 /// # })
227134 /// ```
228135 pub async fn write ( & self ) -> RwLockWriteGuard < ' _ , T > {
229- pub struct WriteFuture < ' a , T : ?Sized > {
230- lock : & ' a RwLock < T > ,
231- opt_key : Option < usize > ,
232- }
233-
234- impl < ' a , T : ?Sized > Future for WriteFuture < ' a , T > {
235- type Output = RwLockWriteGuard < ' a , T > ;
236-
237- fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
238- loop {
239- // If the current task is in the set, remove it.
240- if let Some ( key) = self . opt_key . take ( ) {
241- self . lock . write_wakers . remove ( key) ;
242- }
243-
244- // Try acquiring a write lock.
245- match self . lock . try_write ( ) {
246- Some ( guard) => return Poll :: Ready ( guard) ,
247- None => {
248- // Insert this lock operation.
249- self . opt_key = Some ( self . lock . write_wakers . insert ( cx) ) ;
250-
251- // If the lock is still acquired for reading or writing, return.
252- if self . lock . state . load ( Ordering :: SeqCst ) != 0 {
253- return Poll :: Pending ;
254- }
255- }
256- }
257- }
258- }
259- }
260-
261- impl < T : ?Sized > Drop for WriteFuture < ' _ , T > {
262- fn drop ( & mut self ) {
263- // If the current task is still in the set, that means it is being cancelled now.
264- if let Some ( key) = self . opt_key {
265- if !self . lock . write_wakers . cancel ( key) {
266- // If no other blocked reader was notified, notify all readers.
267- self . lock . read_wakers . notify_all ( ) ;
268- }
269- }
270- }
271- }
272-
273- WriteFuture {
274- lock : self ,
275- opt_key : None ,
276- }
277- . await
136+ self . inner . write ( )
278137 }
279138
280139 /// Attempts to acquire a write lock.
@@ -301,11 +160,7 @@ impl<T: ?Sized> RwLock<T> {
301160 /// # })
302161 /// ```
303162 pub fn try_write ( & self ) -> Option < RwLockWriteGuard < ' _ , T > > {
304- if self . state . compare_and_swap ( 0 , WRITE_LOCK , Ordering :: SeqCst ) == 0 {
305- Some ( RwLockWriteGuard ( self ) )
306- } else {
307- None
308- }
163+ self . inner . try_write ( )
309164 }
310165
311166 /// Consumes the lock, returning the underlying data.
@@ -318,8 +173,11 @@ impl<T: ?Sized> RwLock<T> {
318173 /// let lock = RwLock::new(10);
319174 /// assert_eq!(lock.into_inner(), 10);
320175 /// ```
321- pub fn into_inner ( self ) -> T where T : Sized {
322- self . value . into_inner ( )
176+ pub fn into_inner ( self ) -> T
177+ where
178+ T : Sized ,
179+ {
180+ self . inner . into_inner ( )
323181 }
324182
325183 /// Returns a mutable reference to the underlying data.
@@ -341,23 +199,13 @@ impl<T: ?Sized> RwLock<T> {
341199 /// # })
342200 /// ```
343201 pub fn get_mut ( & mut self ) -> & mut T {
344- unsafe { & mut * self . value . get ( ) }
202+ self . inner . get_mut ( )
345203 }
346204}
347205
348206impl < T : ?Sized + fmt:: Debug > fmt:: Debug for RwLock < T > {
349207 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
350- struct Locked ;
351- impl fmt:: Debug for Locked {
352- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
353- f. write_str ( "<locked>" )
354- }
355- }
356-
357- match self . try_read ( ) {
358- None => f. debug_struct ( "RwLock" ) . field ( "data" , & Locked ) . finish ( ) ,
359- Some ( guard) => f. debug_struct ( "RwLock" ) . field ( "data" , & & * guard) . finish ( ) ,
360- }
208+ self . inner . fmt ( f)
361209 }
362210}
363211
@@ -374,39 +222,34 @@ impl<T: ?Sized + Default> Default for RwLock<T> {
374222}
375223
376224/// A guard that releases the read lock when dropped.
377- pub struct RwLockReadGuard < ' a , T : ?Sized > ( & ' a RwLock < T > ) ;
225+ pub struct RwLockReadGuard < ' a , T : ?Sized > ( & ' a RawRwLockReadGuard < T > ) ;
378226
379227unsafe impl < T : ?Sized + Send > Send for RwLockReadGuard < ' _ , T > { }
380228unsafe impl < T : ?Sized + Sync > Sync for RwLockReadGuard < ' _ , T > { }
381229
382230impl < T : ?Sized > Drop for RwLockReadGuard < ' _ , T > {
383231 fn drop ( & mut self ) {
384- let state = self . 0 . state . fetch_sub ( ONE_READ , Ordering :: SeqCst ) ;
385-
386- // If this was the last reader, notify a blocked writer if none were notified already.
387- if state & READ_COUNT_MASK == ONE_READ {
388- self . 0 . write_wakers . notify_any ( ) ;
389- }
232+ self . 0 . drop ( )
390233 }
391234}
392235
393236impl < T : ?Sized + fmt:: Debug > fmt:: Debug for RwLockReadGuard < ' _ , T > {
394237 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
395- fmt:: Debug :: fmt ( & * * self , f)
238+ self . 0 . fmt ( f)
396239 }
397240}
398241
399242impl < T : ?Sized + fmt:: Display > fmt:: Display for RwLockReadGuard < ' _ , T > {
400243 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
401- ( * * self ) . fmt ( f)
244+ self . 0 . fmt ( f)
402245 }
403246}
404247
405248impl < T : ?Sized > Deref for RwLockReadGuard < ' _ , T > {
406249 type Target = T ;
407250
408251 fn deref ( & self ) -> & T {
409- unsafe { & * self . 0 . value . get ( ) }
252+ self . 0 . deref ( )
410253 }
411254}
412255
0 commit comments