@@ -42,7 +42,6 @@ impl RawMutex {
42
42
RawLockFuture {
43
43
mutex : self ,
44
44
opt_key : None ,
45
- acquired : false ,
46
45
}
47
46
}
48
47
@@ -72,16 +71,42 @@ impl RawMutex {
72
71
73
72
struct RawLockFuture < ' a > {
74
73
mutex : & ' a RawMutex ,
74
+ /// None indicates that the Future isn't yet polled, or has already returned `Ready`.
75
+ /// RawLockFuture does not distinguish between these two states.
75
76
opt_key : Option < NonZeroUsize > ,
76
- acquired : bool ,
77
+ }
78
+
79
+ impl < ' a > RawLockFuture < ' a > {
80
+ /// Remove waker registration. This should be called upon successful acqusition of the lock.
81
+ fn deregister_waker ( & mut self , acquired : bool ) {
82
+ if let Some ( key) = self . opt_key . take ( ) {
83
+ let mut blocked = self . mutex . blocked . lock ( ) ;
84
+ let opt_waker = unsafe { blocked. remove ( key) } ;
85
+
86
+ if opt_waker. is_none ( ) && !acquired {
87
+ // We were awoken but didn't acquire the lock. Wake up another task.
88
+ blocked. wake_one_weak ( ) ;
89
+ }
90
+
91
+ if blocked. is_empty ( ) {
92
+ self . mutex . state . fetch_and ( !BLOCKED , Ordering :: Relaxed ) ;
93
+ }
94
+ }
95
+ }
96
+
97
+ /// Cold path of drop. Only to be hit when locking is cancelled.
98
+ #[ cold]
99
+ fn drop_slow ( & mut self ) {
100
+ self . deregister_waker ( false ) ;
101
+ }
77
102
}
78
103
79
104
impl < ' a > Future for RawLockFuture < ' a > {
80
105
type Output = ( ) ;
81
106
82
107
fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
83
108
if self . mutex . try_lock ( ) {
84
- self . acquired = true ;
109
+ self . deregister_waker ( true ) ;
85
110
Poll :: Ready ( ( ) )
86
111
} else {
87
112
let mut blocked = self . mutex . blocked . lock ( ) ;
@@ -112,7 +137,8 @@ impl<'a> Future for RawLockFuture<'a> {
112
137
// Try locking again because it's possible the mutex got unlocked just
113
138
// before the current task was registered as a blocked task.
114
139
if self . mutex . try_lock ( ) {
115
- self . acquired = true ;
140
+ std:: mem:: drop ( blocked) ;
141
+ self . deregister_waker ( true ) ;
116
142
Poll :: Ready ( ( ) )
117
143
} else {
118
144
Poll :: Pending
@@ -122,19 +148,11 @@ impl<'a> Future for RawLockFuture<'a> {
122
148
}
123
149
124
150
impl Drop for RawLockFuture < ' _ > {
151
+ #[ inline]
125
152
fn drop ( & mut self ) {
126
- if let Some ( key) = self . opt_key {
127
- let mut blocked = self . mutex . blocked . lock ( ) ;
128
- let opt_waker = unsafe { blocked. remove ( key) } ;
129
-
130
- if opt_waker. is_none ( ) && !self . acquired {
131
- // We were awoken but didn't acquire the lock. Wake up another task.
132
- blocked. wake_one_weak ( ) ;
133
- }
134
-
135
- if blocked. is_empty ( ) {
136
- self . mutex . state . fetch_and ( !BLOCKED , Ordering :: Relaxed ) ;
137
- }
153
+ if self . opt_key . is_some ( ) {
154
+ // This cold path is only going to be reached when we drop the future when locking is cancelled.
155
+ self . drop_slow ( ) ;
138
156
}
139
157
}
140
158
}
0 commit comments