@@ -108,32 +108,26 @@ impl<T> RwLock<T> {
108108 type Output = RwLockReadGuard < ' a , T > ;
109109
110110 fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
111- let poll = match self . lock . try_read ( ) {
112- Some ( guard) => Poll :: Ready ( guard) ,
113- None => {
114- // Insert this lock operation.
115- match self . opt_key {
116- None => self . opt_key = Some ( self . lock . read_wakers . insert ( cx) ) ,
117- Some ( key) => self . lock . read_wakers . update ( key, cx) ,
118- }
119-
120- // Try locking again because it's possible the lock got unlocked just
121- // before the current task was inserted into the waker set.
122- match self . lock . try_read ( ) {
123- Some ( guard) => Poll :: Ready ( guard) ,
124- None => Poll :: Pending ,
125- }
126- }
127- } ;
128-
129- if poll. is_ready ( ) {
111+ loop {
130112 // If the current task is in the set, remove it.
131113 if let Some ( key) = self . opt_key . take ( ) {
132- self . lock . read_wakers . complete ( key) ;
114+ self . lock . read_wakers . remove ( key) ;
133115 }
134- }
135116
136- poll
117+ // Try acquiring a read lock.
118+ match self . lock . try_read ( ) {
119+ Some ( guard) => return Poll :: Ready ( guard) ,
120+ None => {
121+ // Insert this lock operation.
122+ self . opt_key = Some ( self . lock . read_wakers . insert ( cx) ) ;
123+
124+ // If the lock is still acquired for writing, return.
125+ if self . lock . state . load ( Ordering :: SeqCst ) & WRITE_LOCK != 0 {
126+ return Poll :: Pending ;
127+ }
128+ }
129+ }
130+ }
137131 }
138132 }
139133
@@ -143,9 +137,10 @@ impl<T> RwLock<T> {
143137 if let Some ( key) = self . opt_key {
144138 self . lock . read_wakers . cancel ( key) ;
145139
146- // If there are no active readers, wake one of the writers.
140+ // If there are no active readers, notify a blocked writer if none were
141+ // notified already.
147142 if self . lock . state . load ( Ordering :: SeqCst ) & READ_COUNT_MASK == 0 {
148- self . lock . write_wakers . notify_one ( ) ;
143+ self . lock . write_wakers . notify_any ( ) ;
149144 }
150145 }
151146 }
@@ -238,32 +233,26 @@ impl<T> RwLock<T> {
238233 type Output = RwLockWriteGuard < ' a , T > ;
239234
240235 fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
241- let poll = match self . lock . try_write ( ) {
242- Some ( guard) => Poll :: Ready ( guard) ,
243- None => {
244- // Insert this lock operation.
245- match self . opt_key {
246- None => self . opt_key = Some ( self . lock . write_wakers . insert ( cx) ) ,
247- Some ( key) => self . lock . write_wakers . update ( key, cx) ,
248- }
249-
250- // Try locking again because it's possible the lock got unlocked just
251- // before the current task was inserted into the waker set.
252- match self . lock . try_write ( ) {
253- Some ( guard) => Poll :: Ready ( guard) ,
254- None => Poll :: Pending ,
255- }
256- }
257- } ;
258-
259- if poll. is_ready ( ) {
236+ loop {
260237 // If the current task is in the set, remove it.
261238 if let Some ( key) = self . opt_key . take ( ) {
262- self . lock . write_wakers . complete ( key) ;
239+ self . lock . write_wakers . remove ( key) ;
263240 }
264- }
265241
266- poll
242+ // Try acquiring a write lock.
243+ match self . lock . try_write ( ) {
244+ Some ( guard) => return Poll :: Ready ( guard) ,
245+ None => {
246+ // Insert this lock operation.
247+ self . opt_key = Some ( self . lock . write_wakers . insert ( cx) ) ;
248+
249+ // If the lock is still acquired for reading or writing, return.
250+ if self . lock . state . load ( Ordering :: SeqCst ) != 0 {
251+ return Poll :: Pending ;
252+ }
253+ }
254+ }
255+ }
267256 }
268257 }
269258
@@ -392,9 +381,9 @@ impl<T> Drop for RwLockReadGuard<'_, T> {
392381 fn drop ( & mut self ) {
393382 let state = self . 0 . state . fetch_sub ( ONE_READ , Ordering :: SeqCst ) ;
394383
395- // If this was the last read, wake one of the writers .
384+ // If this was the last reader, notify a blocked writer if none were notified already .
396385 if state & READ_COUNT_MASK == ONE_READ {
397- self . 0 . write_wakers . notify_one ( ) ;
386+ self . 0 . write_wakers . notify_any ( ) ;
398387 }
399388 }
400389}
@@ -431,8 +420,9 @@ impl<T> Drop for RwLockWriteGuard<'_, T> {
431420
432421 // Notify all blocked readers.
433422 if !self . 0 . read_wakers . notify_all ( ) {
434- // If there were no blocked readers, notify a blocked writer.
435- self . 0 . write_wakers . notify_one ( ) ;
423+ // If there were no blocked readers, notify a blocked writer if none were notified
424+ // already.
425+ self . 0 . write_wakers . notify_any ( ) ;
436426 }
437427 }
438428}
0 commit comments