@@ -202,12 +202,18 @@ impl WaitQueue {
202202 pub fn notify_one < T > (
203203 mut guard : SpinMutexGuard < ' _ , WaitVariable < T > > ,
204204 ) -> 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.
205209 unsafe {
206- if let Some ( entry ) = guard. queue . inner . pop ( ) {
210+ let tcs = guard. queue . inner . pop ( ) . map ( |entry| -> Tcs {
207211 let mut entry_guard = entry. lock ( ) ;
208- let tcs = entry_guard. tcs ;
209212 entry_guard. wake = true ;
210- drop ( entry_guard) ;
213+ entry_guard. tcs
214+ } ) ;
215+
216+ if let Some ( tcs) = tcs {
211217 Ok ( WaitGuard { mutex_guard : Some ( guard) , notified_tcs : NotifiedTcs :: Single ( tcs) } )
212218 } else {
213219 Err ( guard)
@@ -223,13 +229,17 @@ impl WaitQueue {
223229 pub fn notify_all < T > (
224230 mut guard : SpinMutexGuard < ' _ , WaitVariable < T > > ,
225231 ) -> 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.
226235 unsafe {
227236 let mut count = 0 ;
228237 while let Some ( entry) = guard. queue . inner . pop ( ) {
229238 count += 1 ;
230239 let mut entry_guard = entry. lock ( ) ;
231240 entry_guard. wake = true ;
232241 }
242+
233243 if let Some ( count) = NonZeroUsize :: new ( count) {
234244 Ok ( WaitGuard { mutex_guard : Some ( guard) , notified_tcs : NotifiedTcs :: All { count } } )
235245 } else {
0 commit comments