summaryrefslogtreecommitdiff
path: root/src/listener.rs
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2016-09-06 19:37:34 +0200
committerYorhel <git@yorhel.nl>2016-09-06 19:37:34 +0200
commitefe595493c9a8dd1e4df3b9045fff012521449c8 (patch)
treecb1d03aaa426707495c58427c69b81c9f62abaea /src/listener.rs
parent39515558ad68edffc6fe52936714fcefbfc58949 (diff)
Add accept() backoff timer + tcp idle timer + minor eventloop API improvements
Diffstat (limited to 'src/listener.rs')
-rw-r--r--src/listener.rs25
1 files changed, 17 insertions, 8 deletions
diff --git a/src/listener.rs b/src/listener.rs
index 293099e..fcac06d 100644
--- a/src/listener.rs
+++ b/src/listener.rs
@@ -2,8 +2,9 @@ use mio::{Ready,Token,Event};
use mio::tcp::TcpListener;
use std::net::SocketAddr;
use std::io::{Result,ErrorKind};
+use std::time::Duration;
use config::Config;
-use eventloop::{Machine,Context,EventLoop};
+use eventloop::{Machine,Context,EventLoop,TToken};
use itf_http;
@@ -11,7 +12,8 @@ use itf_http;
struct Listener {
sock: TcpListener,
addr: SocketAddr,
- io: Token
+ io: Token,
+ timeout: TToken,
}
@@ -22,7 +24,8 @@ impl Listener {
Ok(Listener {
sock: sock,
addr: *addr,
- io: Token(0)
+ io: Token(0),
+ timeout: TToken(0),
})
}
}
@@ -30,8 +33,8 @@ impl Listener {
impl Machine for Listener {
fn init(&mut self, ctx: &mut Context) {
- self.io = ctx.assign();
- ctx.register(&self.sock, self.io, Ready::readable());
+ self.io = ctx.register(&self.sock, Ready::readable());
+ self.timeout = ctx.alloc_timeout();
info!("Listening on {}", self.addr);
}
@@ -42,11 +45,13 @@ impl Machine for Listener {
match err.kind() {
ErrorKind::WouldBlock |
ErrorKind::Interrupted |
- ErrorKind::TimedOut => { },
+ ErrorKind::TimedOut => { /* Uninteresting temporary errors */ },
_ => {
error!("Error accepting on {}: {}", self.addr, err);
- // If the error is persistent, we may be getting into an infinite loop.
- // TODO: Have a back-off timer here (especially for EMFILE).
+ // Stop listening for short time. If this error is not persistent (like
+ // EMFILE), it will solve itself by just waiting. Not much else we can do.
+ ctx.deregister(&self.sock, self.io);
+ ctx.reset_timeout(self.timeout, Duration::from_millis(500));
}
}
},
@@ -56,6 +61,10 @@ impl Machine for Listener {
}
}
}
+
+ fn timeout(&mut self, ctx: &mut Context, _: TToken) {
+ self.io = ctx.register(&self.sock, Ready::readable());
+ }
}