Skip to content

Commit 472c87b

Browse files
committed
Fix #1898
Semaphore::release() must also be called when it is in the waiting state.
1 parent e5debd6 commit 472c87b

File tree

1 file changed

+7
-12
lines changed

1 file changed

+7
-12
lines changed

tokio/src/sync/mutex.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -86,29 +86,24 @@ impl<T> Mutex<T> {
8686

8787
/// A future that resolves on acquiring the lock and returns the `MutexGuard`.
8888
pub async fn lock(&self) -> MutexGuard<'_, T> {
89-
let mut permit = semaphore::Permit::new();
90-
poll_fn(|cx| permit.poll_acquire(cx, &self.s))
89+
let mut guard = MutexGuard {
90+
lock: self,
91+
permit: semaphore::Permit::new(),
92+
};
93+
poll_fn(|cx| guard.permit.poll_acquire(cx, &self.s))
9194
.await
9295
.unwrap_or_else(|_| {
9396
// The semaphore was closed. but, we never explicitly close it, and we have a
9497
// handle to it through the Arc, which means that this can never happen.
9598
unreachable!()
9699
});
97-
98-
MutexGuard { lock: self, permit }
100+
guard
99101
}
100102
}
101103

102104
impl<'a, T> Drop for MutexGuard<'a, T> {
103105
fn drop(&mut self) {
104-
if self.permit.is_acquired() {
105-
self.permit.release(&self.lock.s);
106-
} else if ::std::thread::panicking() {
107-
// A guard _should_ always hold its permit, but if the thread is already panicking,
108-
// we don't want to generate a panic-while-panicing, since that's just unhelpful!
109-
} else {
110-
unreachable!("Permit not held when MutexGuard was dropped")
111-
}
106+
self.permit.release(&self.lock.s);
112107
}
113108
}
114109

0 commit comments

Comments
 (0)