@@ -22,8 +22,9 @@ impl<T: ?Sized> fmt::Debug for RwLock<T> {
22
22
let state = self . state . load ( Ordering :: SeqCst ) ;
23
23
f. debug_struct ( "RwLock" )
24
24
. field ( "is_locked" , & ( ( state & IS_LOCKED ) != 0 ) )
25
- . field ( "has_waiters" , & ( ( state & HAS_WAITERS ) != 0 ) )
26
- . field ( "readers" , & ( ( state & READ_COUNT_MASK ) >> 2 ) )
25
+ . field ( "has_writers" , & ( ( state & HAS_WRITERS ) != 0 ) )
26
+ . field ( "has_readers" , & ( ( state & HAS_READERS ) != 0 ) )
27
+ . field ( "active_readers" , & ( ( state & READ_COUNT_MASK ) >> 3 ) )
27
28
. finish ( )
28
29
}
29
30
}
@@ -51,10 +52,11 @@ impl Waiter {
51
52
52
53
#[ allow( clippy:: identity_op) ]
53
54
const IS_LOCKED : usize = 1 << 0 ;
54
- const HAS_WAITERS : usize = 1 << 1 ;
55
- const ONE_READER : usize = 1 << 2 ;
55
+ const HAS_WRITERS : usize = 1 << 1 ;
56
+ const HAS_READERS : usize = 1 << 2 ;
57
+ const ONE_READER : usize = 1 << 3 ;
56
58
const READ_COUNT_MASK : usize = !( ONE_READER - 1 ) ;
57
- const MAX_READERS : usize = usize:: max_value ( ) >> 2 ;
59
+ const MAX_READERS : usize = usize:: max_value ( ) >> 3 ;
58
60
59
61
impl < T > RwLock < T > {
60
62
/// Creates a new futures-aware read-write lock.
@@ -170,6 +172,9 @@ impl<T: ?Sized> RwLock<T> {
170
172
// No need to check whether another waiter needs to be
171
173
// woken up since no other readers depend on this.
172
174
readers. remove ( wait_key) ;
175
+ if readers. is_empty ( ) {
176
+ self . state . fetch_and ( !HAS_READERS , Ordering :: Relaxed ) ;
177
+ }
173
178
}
174
179
}
175
180
@@ -190,7 +195,7 @@ impl<T: ?Sized> RwLock<T> {
190
195
}
191
196
}
192
197
if writers. is_empty ( ) {
193
- self . state . fetch_and ( !HAS_WAITERS , Ordering :: Relaxed ) ;
198
+ self . state . fetch_and ( !HAS_WRITERS , Ordering :: Relaxed ) ;
194
199
}
195
200
}
196
201
}
@@ -248,6 +253,9 @@ impl<'a, T: ?Sized> Future for RwLockReadFuture<'a, T> {
248
253
let mut readers = rwlock. read_waiters . lock ( ) . unwrap ( ) ;
249
254
if self . wait_key == WAIT_KEY_NONE {
250
255
self . wait_key = readers. insert ( Waiter :: Waiting ( cx. waker ( ) . clone ( ) ) ) ;
256
+ if readers. len ( ) == 1 {
257
+ rwlock. state . fetch_or ( HAS_READERS , Ordering :: Relaxed ) ;
258
+ }
251
259
} else {
252
260
readers[ self . wait_key ] . register ( cx. waker ( ) ) ;
253
261
}
@@ -322,7 +330,7 @@ impl<'a, T: ?Sized> Future for RwLockWriteFuture<'a, T> {
322
330
if self . wait_key == WAIT_KEY_NONE {
323
331
self . wait_key = writers. insert ( Waiter :: Waiting ( cx. waker ( ) . clone ( ) ) ) ;
324
332
if writers. len ( ) == 1 {
325
- rwlock. state . fetch_or ( HAS_WAITERS , Ordering :: Relaxed ) ;
333
+ rwlock. state . fetch_or ( HAS_WRITERS , Ordering :: Relaxed ) ;
326
334
}
327
335
} else {
328
336
writers[ self . wait_key ] . register ( cx. waker ( ) ) ;
@@ -373,7 +381,7 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockReadGuard<'_, T> {
373
381
impl < T : ?Sized > Drop for RwLockReadGuard < ' _ , T > {
374
382
fn drop ( & mut self ) {
375
383
let old_state = self . rwlock . state . fetch_sub ( ONE_READER , Ordering :: SeqCst ) ;
376
- if old_state & READ_COUNT_MASK == ONE_READER && old_state & HAS_WAITERS != 0 {
384
+ if old_state & READ_COUNT_MASK == ONE_READER && old_state & HAS_WRITERS != 0 {
377
385
let mut writers = self . rwlock . write_waiters . lock ( ) . unwrap ( ) ;
378
386
if let Some ( ( _, waiter) ) = writers. iter_mut ( ) . next ( ) {
379
387
waiter. wake ( ) ;
@@ -414,7 +422,7 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockWriteGuard<'_, T> {
414
422
impl < T : ?Sized > Drop for RwLockWriteGuard < ' _ , T > {
415
423
fn drop ( & mut self ) {
416
424
let old_state = self . rwlock . state . fetch_and ( !IS_LOCKED , Ordering :: AcqRel ) ;
417
- match ( old_state & HAS_WAITERS , old_state & READ_COUNT_MASK ) {
425
+ match ( old_state & HAS_WRITERS , old_state & HAS_READERS ) {
418
426
( 0 , 0 ) => { }
419
427
( 0 , _) => {
420
428
let mut readers = self . rwlock . read_waiters . lock ( ) . unwrap ( ) ;
0 commit comments