mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-15 00:00:15 +02:00
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
This commit is contained in:
committed by
Carl Lerche
parent
34d751bf92
commit
524e66314f
+31
-2
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user