summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Birr-Pixton <jpixton@gmail.com>2017-05-06 18:23:30 +0100
committerJoseph Birr-Pixton <jpixton@gmail.com>2017-05-06 18:23:30 +0100
commit14e9529e406065efe23f4de9112601d896820716 (patch)
tree2299d98c6ec22e988b0d0611d7dad2bc9b82c505
parentdac2274e80495888768ee3ff18df34891d12ba1e (diff)
Update mio dependency to 0.6v/0.6.0
-rw-r--r--Cargo.toml2
-rw-r--r--examples/tlsclient.rs64
-rw-r--r--examples/tlsserver.rs158
3 files changed, 119 insertions, 105 deletions
diff --git a/Cargo.toml b/Cargo.toml
index dd28f8ee..0a37b8c4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,7 +24,7 @@ logging = ["log"]
[dev-dependencies]
log = "0.3.7"
env_logger = "0.4.2"
-mio = "0.5"
+mio = "0.6"
docopt = "0.7"
rustc-serialize = "0.3"
webpki-roots = "0.9"
diff --git a/examples/tlsclient.rs b/examples/tlsclient.rs
index ec881118..c01a83bd 100644
--- a/examples/tlsclient.rs
+++ b/examples/tlsclient.rs
@@ -33,22 +33,17 @@ struct TlsClient {
tls_session: rustls::ClientSession,
}
-impl mio::Handler for TlsClient {
- type Timeout = ();
- type Message = ();
-
- /// Called by mio each time events we register() for happen.
+impl TlsClient {
fn ready(&mut self,
- event_loop: &mut mio::EventLoop<TlsClient>,
- token: mio::Token,
- events: mio::EventSet) {
- assert_eq!(token, CLIENT);
+ poll: &mut mio::Poll,
+ ev: &mio::Event) {
+ assert_eq!(ev.token(), CLIENT);
- if events.is_readable() {
+ if ev.readiness().is_readable() {
self.do_read();
}
- if events.is_writable() {
+ if ev.readiness().is_writable() {
self.do_write();
}
@@ -57,16 +52,7 @@ impl mio::Handler for TlsClient {
process::exit(if self.clean_closure { 0 } else { 1 });
}
- self.reregister(event_loop);
- }
-
- // XXX: this won't be called currently, but could be used in the future
- // to have timeout behaviour.
- fn timeout(&mut self,
- _event_loop: &mut mio::EventLoop<TlsClient>,
- _timeout: <TlsClient as mio::Handler>::Timeout) {
- println!("connection timed out");
- process::exit(1);
+ self.reregister(poll);
}
}
@@ -158,34 +144,34 @@ impl TlsClient {
self.tls_session.write_tls(&mut self.socket).unwrap();
}
- fn register(&self, event_loop: &mut mio::EventLoop<TlsClient>) {
- event_loop.register(&self.socket,
+ fn register(&self, poll: &mut mio::Poll) {
+ poll.register(&self.socket,
CLIENT,
- self.event_set(),
+ self.ready_interest(),
mio::PollOpt::level() | mio::PollOpt::oneshot())
.unwrap();
}
- fn reregister(&self, event_loop: &mut mio::EventLoop<TlsClient>) {
- event_loop.reregister(&self.socket,
+ fn reregister(&self, poll: &mut mio::Poll) {
+ poll.reregister(&self.socket,
CLIENT,
- self.event_set(),
+ self.ready_interest(),
mio::PollOpt::level() | mio::PollOpt::oneshot())
.unwrap();
}
// Use wants_read/wants_write to register for different mio-level
// IO readiness events.
- fn event_set(&self) -> mio::EventSet {
+ fn ready_interest(&self) -> mio::Ready {
let rd = self.tls_session.wants_read();
let wr = self.tls_session.wants_write();
if rd && wr {
- mio::EventSet::readable() | mio::EventSet::writable()
+ mio::Ready::readable() | mio::Ready::writable()
} else if wr {
- mio::EventSet::writable()
+ mio::Ready::writable()
} else {
- mio::EventSet::readable()
+ mio::Ready::readable()
}
}
@@ -469,7 +455,17 @@ fn main() {
tlsclient.read_source_to_end(&mut stdin).unwrap();
}
- let mut event_loop = mio::EventLoop::new().unwrap();
- tlsclient.register(&mut event_loop);
- event_loop.run(&mut tlsclient).unwrap();
+ let mut poll = mio::Poll::new()
+ .unwrap();
+ let mut events = mio::Events::with_capacity(32);
+ tlsclient.register(&mut poll);
+
+ loop {
+ poll.poll(&mut events, None)
+ .unwrap();
+
+ for ev in events.iter() {
+ tlsclient.ready(&mut poll, &ev);
+ }
+ }
}
diff --git a/examples/tlsserver.rs b/examples/tlsserver.rs
index 8a05aec3..7e161676 100644
--- a/examples/tlsserver.rs
+++ b/examples/tlsserver.rs
@@ -1,8 +1,6 @@
use std::sync::Arc;
extern crate mio;
-use mio::util::Slab;
-use mio::TryRead;
use mio::tcp::{TcpListener, TcpStream, Shutdown};
#[macro_use]
@@ -12,6 +10,7 @@ use std::fs;
use std::io;
use std::net;
use std::io::{Write, Read, BufReader};
+use std::collections::HashMap;
extern crate rustc_serialize;
extern crate docopt;
@@ -44,69 +43,56 @@ enum ServerMode {
/// connections, and a TLS server configuration.
struct TlsServer {
server: TcpListener,
- connections: Slab<Connection>,
+ connections: HashMap<mio::Token, Connection>,
+ next_id: usize,
tls_config: Arc<rustls::ServerConfig>,
mode: ServerMode,
}
impl TlsServer {
fn new(server: TcpListener, mode: ServerMode, cfg: Arc<rustls::ServerConfig>) -> TlsServer {
- let slab = Slab::new_starting_at(mio::Token(1), 256);
-
TlsServer {
server: server,
- connections: slab,
+ connections: HashMap::new(),
+ next_id: 2,
tls_config: cfg,
mode: mode,
}
}
-}
-impl mio::Handler for TlsServer {
- type Timeout = ();
- type Message = ();
-
- fn ready(&mut self,
- event_loop: &mut mio::EventLoop<TlsServer>,
- token: mio::Token,
- events: mio::EventSet) {
- match token {
- // Our listening socket: we have a new connection.
- LISTENER => {
- match self.server.accept() {
- Ok(Some((socket, addr))) => {
- info!("Accepting new connection from {:?}", addr);
-
- let tls_session = rustls::ServerSession::new(&self.tls_config);
- let mode = self.mode.clone();
-
- match self.connections
- .insert_with(|token| Connection::new(socket, token, mode, tls_session)) {
- Some(token) => {
- self.connections[token].register(event_loop);
- }
- None => {
- error!("Too many connections: rejecting new connection");
- }
- }
- }
- Ok(None) => {}
- Err(e) => {
- println!("encountered error while accepting connection; err={:?}", e);
- event_loop.shutdown();
- }
- }
+ fn accept(&mut self, poll: &mut mio::Poll) -> bool {
+ match self.server.accept() {
+ Ok((socket, addr)) => {
+ info!("Accepting new connection from {:?}", addr);
+
+ let tls_session = rustls::ServerSession::new(&self.tls_config);
+ let mode = self.mode.clone();
+
+ let token = mio::Token(self.next_id);
+ self.next_id += 1;
+
+ self.connections.insert(token, Connection::new(socket, token, mode, tls_session));
+ self.connections[&token].register(poll);
+ true
+ }
+ Err(e) => {
+ println!("encountered error while accepting connection; err={:?}", e);
+ false
}
+ }
+ }
- // A connection socket.
- _ => {
- if self.connections.contains(token) {
- self.connections[token].ready(event_loop, events);
+ fn conn_event(&mut self, poll: &mut mio::Poll, event: &mio::Event) {
+ let token = event.token();
- if self.connections[token].is_closed() {
- self.connections.remove(token);
- }
- }
+ if self.connections.contains_key(&token) {
+ self.connections
+ .get_mut(&token)
+ .unwrap()
+ .ready(poll, event);
+
+ if self.connections[&token].is_closed() {
+ self.connections.remove(&token);
}
}
}
@@ -139,6 +125,21 @@ fn open_back(mode: &ServerMode) -> Option<TcpStream> {
}
}
+/// This used to be conveniently exposed by mio: map EWOULDBLOCK
+/// errors to something less-errory.
+fn try_read(r: io::Result<usize>) -> io::Result<Option<usize>> {
+ match r {
+ Ok(len) => Ok(Some(len)),
+ Err(e) => {
+ if e.kind() == io::ErrorKind::WouldBlock {
+ Ok(None)
+ } else {
+ Err(e)
+ }
+ }
+ }
+}
+
impl Connection {
fn new(socket: TcpStream,
token: mio::Token,
@@ -158,17 +159,17 @@ impl Connection {
}
/// We're a connection, and we have something to do.
- fn ready(&mut self, event_loop: &mut mio::EventLoop<TlsServer>, events: mio::EventSet) {
+ fn ready(&mut self, poll: &mut mio::Poll, ev: &mio::Event) {
// If we're readable: read some TLS. Then
// see if that yielded new plaintext. Then
// see if the backend is readable too.
- if events.is_readable() {
+ if ev.readiness().is_readable() {
self.do_tls_read();
self.try_plain_read();
self.try_back_read();
}
- if events.is_writable() {
+ if ev.readiness().is_writable() {
self.do_tls_write();
}
@@ -176,7 +177,7 @@ impl Connection {
let _ = self.socket.shutdown(Shutdown::Both);
self.close_back();
} else {
- self.reregister(event_loop);
+ self.reregister(poll);
}
}
@@ -244,7 +245,7 @@ impl Connection {
// Try a non-blocking read.
let mut buf = [0u8; 1024];
let back = self.back.as_mut().unwrap();
- let rc = back.try_read(&mut buf);
+ let rc = try_read(back.read(&mut buf));
if rc.is_err() {
error!("backend read failed: {:?}", rc);
@@ -303,33 +304,33 @@ impl Connection {
}
}
- fn register(&self, event_loop: &mut mio::EventLoop<TlsServer>) {
- event_loop.register(&self.socket,
+ fn register(&self, poll: &mut mio::Poll) {
+ poll.register(&self.socket,
self.token,
self.event_set(),
mio::PollOpt::level() | mio::PollOpt::oneshot())
.unwrap();
if self.back.is_some() {
- event_loop.register(self.back.as_ref().unwrap(),
+ poll.register(self.back.as_ref().unwrap(),
self.token,
- mio::EventSet::readable(),
+ mio::Ready::readable(),
mio::PollOpt::level() | mio::PollOpt::oneshot())
.unwrap();
}
}
- fn reregister(&self, event_loop: &mut mio::EventLoop<TlsServer>) {
- event_loop.reregister(&self.socket,
+ fn reregister(&self, poll: &mut mio::Poll) {
+ poll.reregister(&self.socket,
self.token,
self.event_set(),
mio::PollOpt::level() | mio::PollOpt::oneshot())
.unwrap();
if self.back.is_some() {
- event_loop.reregister(self.back.as_ref().unwrap(),
+ poll.reregister(self.back.as_ref().unwrap(),
self.token,
- mio::EventSet::readable(),
+ mio::Ready::readable(),
mio::PollOpt::level() | mio::PollOpt::oneshot())
.unwrap();
}
@@ -337,16 +338,16 @@ impl Connection {
/// What IO events we're currently waiting for,
/// based on wants_read/wants_write.
- fn event_set(&self) -> mio::EventSet {
+ fn event_set(&self) -> mio::Ready {
let rd = self.tls_session.wants_read();
let wr = self.tls_session.wants_write();
if rd && wr {
- mio::EventSet::readable() | mio::EventSet::writable()
+ mio::Ready::readable() | mio::Ready::writable()
} else if wr {
- mio::EventSet::writable()
+ mio::Ready::writable()
} else {
- mio::EventSet::readable()
+ mio::Ready::readable()
}
}
@@ -545,10 +546,11 @@ fn main() {
let config = make_config(&args);
let listener = TcpListener::bind(&addr).expect("cannot listen on port");
- let mut event_loop = mio::EventLoop::new().unwrap();
- event_loop.register(&listener,
+ let mut poll = mio::Poll::new()
+ .unwrap();
+ poll.register(&listener,
LISTENER,
- mio::EventSet::readable(),
+ mio::Ready::readable(),
mio::PollOpt::level())
.unwrap();
@@ -561,5 +563,21 @@ fn main() {
};
let mut tlsserv = TlsServer::new(listener, mode, config);
- event_loop.run(&mut tlsserv).unwrap();
+
+ let mut events = mio::Events::with_capacity(256);
+ loop {
+ poll.poll(&mut events, None)
+ .unwrap();
+
+ for event in events.iter() {
+ match event.token() {
+ LISTENER => {
+ if !tlsserv.accept(&mut poll) {
+ break;
+ }
+ }
+ _ => tlsserv.conn_event(&mut poll, &event)
+ }
+ }
+ }
}