Skip to content

Commit d498768

Browse files
committed
Remove the acquired bool from RawLockFuture.
1 parent 04e8c16 commit d498768

File tree

1 file changed

+34
-16
lines changed

1 file changed

+34
-16
lines changed

src/sync/mutex.rs

+34-16
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ impl RawMutex {
4242
RawLockFuture {
4343
mutex: self,
4444
opt_key: None,
45-
acquired: false,
4645
}
4746
}
4847

@@ -72,16 +71,42 @@ impl RawMutex {
7271

7372
struct RawLockFuture<'a> {
7473
mutex: &'a RawMutex,
74+
/// None indicates that the Future isn't yet polled, or has already returned `Ready`.
75+
/// RawLockFuture does not distinguish between these two states.
7576
opt_key: Option<NonZeroUsize>,
76-
acquired: bool,
77+
}
78+
79+
impl<'a> RawLockFuture<'a> {
80+
/// Remove waker registration. This should be called upon successful acqusition of the lock.
81+
fn deregister_waker(&mut self, acquired: bool) {
82+
if let Some(key) = self.opt_key.take() {
83+
let mut blocked = self.mutex.blocked.lock();
84+
let opt_waker = unsafe { blocked.remove(key) };
85+
86+
if opt_waker.is_none() && !acquired {
87+
// We were awoken but didn't acquire the lock. Wake up another task.
88+
blocked.wake_one_weak();
89+
}
90+
91+
if blocked.is_empty() {
92+
self.mutex.state.fetch_and(!BLOCKED, Ordering::Relaxed);
93+
}
94+
}
95+
}
96+
97+
/// Cold path of drop. Only to be hit when locking is cancelled.
98+
#[cold]
99+
fn drop_slow(&mut self) {
100+
self.deregister_waker(false);
101+
}
77102
}
78103

79104
impl<'a> Future for RawLockFuture<'a> {
80105
type Output = ();
81106

82107
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
83108
if self.mutex.try_lock() {
84-
self.acquired = true;
109+
self.deregister_waker(true);
85110
Poll::Ready(())
86111
} else {
87112
let mut blocked = self.mutex.blocked.lock();
@@ -112,7 +137,8 @@ impl<'a> Future for RawLockFuture<'a> {
112137
// Try locking again because it's possible the mutex got unlocked just
113138
// before the current task was registered as a blocked task.
114139
if self.mutex.try_lock() {
115-
self.acquired = true;
140+
std::mem::drop(blocked);
141+
self.deregister_waker(true);
116142
Poll::Ready(())
117143
} else {
118144
Poll::Pending
@@ -122,19 +148,11 @@ impl<'a> Future for RawLockFuture<'a> {
122148
}
123149

124150
impl Drop for RawLockFuture<'_> {
151+
#[inline]
125152
fn drop(&mut self) {
126-
if let Some(key) = self.opt_key {
127-
let mut blocked = self.mutex.blocked.lock();
128-
let opt_waker = unsafe { blocked.remove(key) };
129-
130-
if opt_waker.is_none() && !self.acquired {
131-
// We were awoken but didn't acquire the lock. Wake up another task.
132-
blocked.wake_one_weak();
133-
}
134-
135-
if blocked.is_empty() {
136-
self.mutex.state.fetch_and(!BLOCKED, Ordering::Relaxed);
137-
}
153+
if self.opt_key.is_some() {
154+
// This cold path is only going to be reached when we drop the future when locking is cancelled.
155+
self.drop_slow();
138156
}
139157
}
140158
}

0 commit comments

Comments
 (0)