summaryrefslogtreecommitdiff
path: root/src/tokio_util.rs
diff options
context:
space:
mode:
authorKevin (Kun) "Kassimo" Qian <kevinkassimo@gmail.com>2019-01-15 17:36:51 -0800
committerRyan Dahl <ry@tinyclouds.org>2019-01-15 20:36:51 -0500
commit431e455642cee8f7258814d6bb9b426a99d1256b (patch)
tree0ebde25e545a0054eca451b9c97bd3e9f393efe3 /src/tokio_util.rs
parentc870cf40823a4900278f8ddf03489338c169878b (diff)
Kill all pending accepts when TCP listener is closed (#1517)
Diffstat (limited to 'src/tokio_util.rs')
-rw-r--r--src/tokio_util.rs20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/tokio_util.rs b/src/tokio_util.rs
index 32542aa43..2eb0211db 100644
--- a/src/tokio_util.rs
+++ b/src/tokio_util.rs
@@ -63,7 +63,25 @@ impl Future for Accept {
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let (stream, addr) = match self.state {
- AcceptState::Pending(ref mut r) => try_ready!(r.poll_accept()),
+ // Similar to try_ready!, but also track/untrack accept task
+ // in TcpListener resource.
+ // In this way, when the listener is closed, the task can be
+ // notified to error out (instead of stuck forever).
+ AcceptState::Pending(ref mut r) => match r.poll_accept() {
+ Ok(futures::prelude::Async::Ready(t)) => {
+ r.untrack_task();
+ t
+ }
+ Ok(futures::prelude::Async::NotReady) => {
+ // Would error out if another accept task is being tracked.
+ r.track_task()?;
+ return Ok(futures::prelude::Async::NotReady);
+ }
+ Err(e) => {
+ r.untrack_task();
+ return Err(From::from(e));
+ }
+ },
AcceptState::Empty => panic!("poll Accept after it's done"),
};