summaryrefslogtreecommitdiffstats
path: root/tokio/src/task/queue.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tokio/src/task/queue.rs')
-rw-r--r--tokio/src/task/queue.rs33
1 files changed, 20 insertions, 13 deletions
diff --git a/tokio/src/task/queue.rs b/tokio/src/task/queue.rs
index a2badc8a..048960a4 100644
--- a/tokio/src/task/queue.rs
+++ b/tokio/src/task/queue.rs
@@ -261,19 +261,26 @@ where
/// If the mutex around the remote queue is poisoned _and_ the current
/// thread is not already panicking. This is safe to call in a `Drop` impl.
fn close_remote(&self) {
- #[allow(clippy::match_wild_err_arm)]
- let mut lock = match self.remote_queue.lock() {
- // If the lock is poisoned, but the thread is already panicking,
- // avoid a double panic. This is necessary since this fn can be
- // called in a drop impl.
- Err(_) if std::thread::panicking() => return,
- Err(_) => panic!("mutex poisoned"),
- Ok(lock) => lock,
- };
- lock.open = false;
-
- while let Some(task) = lock.queue.pop_front() {
- task.shutdown();
+ loop {
+ #[allow(clippy::match_wild_err_arm)]
+ let mut lock = match self.remote_queue.lock() {
+ // If the lock is poisoned, but the thread is already panicking,
+ // avoid a double panic. This is necessary since this fn can be
+ // called in a drop impl.
+ Err(_) if std::thread::panicking() => return,
+ Err(_) => panic!("mutex poisoned"),
+ Ok(lock) => lock,
+ };
+ lock.open = false;
+
+ if let Some(task) = lock.queue.pop_front() {
+ // Release lock before dropping task, in case
+ // task tries to re-schedule in its Drop.
+ drop(lock);
+ task.shutdown();
+ } else {
+ return;
+ }
}
}