@@ -917,10 +917,14 @@ impl Notified<'_> {
917
917
}
918
918
}
919
919
920
+ let mut old_waker = None ;
920
921
if waker. is_some ( ) {
921
922
// Safety: called while locked.
923
+ //
924
+ // The use of `old_waiter` here is not necessary, as the field is always
925
+ // None when we reach this line.
922
926
unsafe {
923
- ( * waiter. get ( ) ) . waker = waker;
927
+ old_waker = std :: mem :: replace ( & mut ( * waiter. get ( ) ) . waker , waker) ;
924
928
}
925
929
}
926
930
@@ -931,6 +935,9 @@ impl Notified<'_> {
931
935
932
936
* state = Waiting ;
933
937
938
+ drop ( waiters) ;
939
+ drop ( old_waker) ;
940
+
934
941
return Poll :: Pending ;
935
942
}
936
943
Waiting => {
@@ -945,12 +952,13 @@ impl Notified<'_> {
945
952
946
953
// Safety: called while locked
947
954
let w = unsafe { & mut * waiter. get ( ) } ;
955
+ let mut old_waker = None ;
948
956
949
957
if w. notified . is_some ( ) {
950
958
// Our waker has been notified and our waiter is already removed from
951
959
// the list. Reset the notification and convert to `Done`.
960
+ old_waker = std:: mem:: take ( & mut w. waker ) ;
952
961
w. notified = None ;
953
- w. waker = None ;
954
962
* state = Done ;
955
963
} else if get_num_notify_waiters_calls ( curr) != * notify_waiters_calls {
956
964
// Before we add a waiter to the list we check if these numbers are
@@ -960,7 +968,7 @@ impl Notified<'_> {
960
968
// We can treat the waiter as notified and remove it from the list, as
961
969
// it would have been notified in the `notify_waiters` call anyways.
962
970
963
- w . waker = None ;
971
+ old_waker = std :: mem :: take ( & mut w . waker ) ;
964
972
965
973
// Safety: we hold the lock, so we have an exclusive access to the list.
966
974
// The list is used in `notify_waiters`, so it must be guarded.
@@ -975,10 +983,14 @@ impl Notified<'_> {
975
983
None => true ,
976
984
} ;
977
985
if should_update {
978
- w. waker = Some ( waker. clone ( ) ) ;
986
+ old_waker = std :: mem :: replace ( & mut w. waker , Some ( waker. clone ( ) ) ) ;
979
987
}
980
988
}
981
989
990
+ // Drop the old waker after releasing the lock.
991
+ drop ( waiters) ;
992
+ drop ( old_waker) ;
993
+
982
994
return Poll :: Pending ;
983
995
}
984
996
@@ -988,6 +1000,9 @@ impl Notified<'_> {
988
1000
// is helpful to visualize the scope of the critical
989
1001
// section.
990
1002
drop ( waiters) ;
1003
+
1004
+ // Drop the old waker after releasing the lock.
1005
+ drop ( old_waker) ;
991
1006
}
992
1007
Done => {
993
1008
return Poll :: Ready ( ( ) ) ;
0 commit comments