summaryrefslogtreecommitdiffstats
path: root/tokio/src/task/local.rs
diff options
context:
space:
mode:
authorEliza Weisman <eliza@buoyant.io>2019-11-27 14:24:44 -0800
committerCarl Lerche <me@carllerche.com>2019-11-27 14:24:44 -0800
commit524e66314faacd9803792ce2a9dc13befd2ceeeb (patch)
tree4cbd061fa263049dc85230ae8eb811c1b57073fb /tokio/src/task/local.rs
parent34d751bf92294b64a3c8ea79a612b796672253a1 (diff)
task: fix panic when dropping `LocalSet` (#1843)
It turns out that the `Scheduler::release` method on `LocalSet`'s `Scheduler` *is* called, when the `Scheduler` is dropped with tasks still running. Currently, that method is `unreachable!`, which means that dropping a `LocalSet` with tasks running will panic. This commit fixes the panic, by pushing released tasks to `pending_drop`. This is the same as `BasicScheduler`. Fixes #1842
Diffstat (limited to 'tokio/src/task/local.rs')
-rw-r--r--tokio/src/task/local.rs33
1 files changed, 31 insertions, 2 deletions
diff --git a/tokio/src/task/local.rs b/tokio/src/task/local.rs
index cb62bd5e..6d0adf31 100644
--- a/tokio/src/task/local.rs
+++ b/tokio/src/task/local.rs
@@ -345,8 +345,9 @@ impl Schedule for Scheduler {
}
}
- fn release(&self, _: Task<Self>) {
- unreachable!("tasks should only be completed locally")
+ fn release(&self, task: Task<Self>) {
+ // This will be called when dropping the local runtime.
+ self.pending_drop.push(task);
}
fn release_local(&self, task: &Task<Self>) {
@@ -724,4 +725,32 @@ mod tests {
join2.await.unwrap()
});
}
+ #[test]
+ fn drop_cancels_tasks() {
+ // This test reproduces issue #1842
+ use crate::sync::oneshot;
+ use std::time::Duration;
+
+ let mut rt = runtime::Builder::new()
+ .enable_time()
+ .basic_scheduler()
+ .build()
+ .unwrap();
+
+ let (started_tx, started_rx) = oneshot::channel();
+
+ let local = LocalSet::new();
+ local.spawn_local(async move {
+ started_tx.send(()).unwrap();
+ loop {
+ crate::time::delay_for(Duration::from_secs(3600)).await;
+ }
+ });
+
+ local.block_on(&mut rt, async {
+ started_rx.await.unwrap();
+ });
+ drop(local);
+ drop(rt);
+ }
}