@@ -202,12 +202,18 @@ impl WaitQueue {
202
202
pub fn notify_one < T > (
203
203
mut guard : SpinMutexGuard < ' _ , WaitVariable < T > > ,
204
204
) -> Result < WaitGuard < ' _ , T > , SpinMutexGuard < ' _ , WaitVariable < T > > > {
205
+ // SAFETY: lifetime of the pop() return value is limited to the map
206
+ // closure (The closure return value is 'static). The underlying
207
+ // stack frame won't be freed until after the WaitGuard created below
208
+ // is dropped.
205
209
unsafe {
206
- if let Some ( entry ) = guard. queue . inner . pop ( ) {
210
+ let tcs = guard. queue . inner . pop ( ) . map ( |entry| -> Tcs {
207
211
let mut entry_guard = entry. lock ( ) ;
208
- let tcs = entry_guard. tcs ;
209
212
entry_guard. wake = true ;
210
- drop ( entry_guard) ;
213
+ entry_guard. tcs
214
+ } ) ;
215
+
216
+ if let Some ( tcs) = tcs {
211
217
Ok ( WaitGuard { mutex_guard : Some ( guard) , notified_tcs : NotifiedTcs :: Single ( tcs) } )
212
218
} else {
213
219
Err ( guard)
@@ -223,13 +229,17 @@ impl WaitQueue {
223
229
pub fn notify_all < T > (
224
230
mut guard : SpinMutexGuard < ' _ , WaitVariable < T > > ,
225
231
) -> Result < WaitGuard < ' _ , T > , SpinMutexGuard < ' _ , WaitVariable < T > > > {
232
+ // SAFETY: lifetime of the pop() return values are limited to the
233
+ // while loop body. The underlying stack frames won't be freed until
234
+ // after the WaitGuard created below is dropped.
226
235
unsafe {
227
236
let mut count = 0 ;
228
237
while let Some ( entry) = guard. queue . inner . pop ( ) {
229
238
count += 1 ;
230
239
let mut entry_guard = entry. lock ( ) ;
231
240
entry_guard. wake = true ;
232
241
}
242
+
233
243
if let Some ( count) = NonZeroUsize :: new ( count) {
234
244
Ok ( WaitGuard { mutex_guard : Some ( guard) , notified_tcs : NotifiedTcs :: All { count } } )
235
245
} else {
0 commit comments