Skip to content

Commit 2f8943d

Browse files
laizycramertj
authored andcommitted
reduce box allocation in bilock.
1 parent fc6bd69 commit 2f8943d

File tree

1 file changed

+6
-3
lines changed

1 file changed

+6
-3
lines changed

futures-util/src/lock/bilock.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ impl<T> BiLock<T> {
8888
/// This function will panic if called outside the context of a future's
8989
/// task.
9090
pub fn poll_lock(&self, cx: &mut Context<'_>) -> Poll<BiLockGuard<'_, T>> {
91+
let mut waker = None;
9192
loop {
9293
match self.arc.state.swap(1, SeqCst) {
9394
// Woohoo, we grabbed the lock!
@@ -99,12 +100,14 @@ impl<T> BiLock<T> {
99100
// A task was previously blocked on this lock, likely our task,
100101
// so we need to update that task.
101102
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);
103106
}
104107
}
105108

106109
// 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()));
108111
let me = Box::into_raw(me) as usize;
109112

110113
match self.arc.state.compare_exchange(1, me, SeqCst, SeqCst) {
@@ -116,7 +119,7 @@ impl<T> BiLock<T> {
116119
// and before the compare_exchange. Deallocate what we just
117120
// allocated and go through the loop again.
118121
Err(0) => unsafe {
119-
drop(Box::from_raw(me as *mut Waker));
122+
waker = Some(Box::from_raw(me as *mut Waker));
120123
},
121124

122125
// The top of this loop set the previous state to 1, so if we

0 commit comments

Comments
 (0)