@@ -88,6 +88,7 @@ impl<T> BiLock<T> {
88
88
/// This function will panic if called outside the context of a future's
89
89
/// task.
90
90
pub fn poll_lock ( & self , cx : & mut Context < ' _ > ) -> Poll < BiLockGuard < ' _ , T > > {
91
+ let mut waker = None ;
91
92
loop {
92
93
match self . arc . state . swap ( 1 , SeqCst ) {
93
94
// Woohoo, we grabbed the lock!
@@ -99,12 +100,14 @@ impl<T> BiLock<T> {
99
100
// A task was previously blocked on this lock, likely our task,
100
101
// so we need to update that task.
101
102
n => unsafe {
102
- drop ( Box :: from_raw ( n as * mut Waker ) ) ;
103
+ let mut prev = Box :: from_raw ( n as * mut Waker ) ;
104
+ * prev = cx. waker ( ) . clone ( ) ;
105
+ waker = Some ( prev) ;
103
106
}
104
107
}
105
108
106
109
// type ascription for safety's sake!
107
- let me: Box < Waker > = Box :: new ( cx. waker ( ) . clone ( ) ) ;
110
+ let me: Box < Waker > = waker . take ( ) . unwrap_or_else ( || Box :: new ( cx. waker ( ) . clone ( ) ) ) ;
108
111
let me = Box :: into_raw ( me) as usize ;
109
112
110
113
match self . arc . state . compare_exchange ( 1 , me, SeqCst , SeqCst ) {
@@ -116,7 +119,7 @@ impl<T> BiLock<T> {
116
119
// and before the compare_exchange. Deallocate what we just
117
120
// allocated and go through the loop again.
118
121
Err ( 0 ) => unsafe {
119
- drop ( Box :: from_raw ( me as * mut Waker ) ) ;
122
+ waker = Some ( Box :: from_raw ( me as * mut Waker ) ) ;
120
123
} ,
121
124
122
125
// The top of this loop set the previous state to 1, so if we
0 commit comments