diff options
author | Joseph Birr-Pixton <jpixton@gmail.com> | 2017-05-06 18:23:30 +0100 |
---|---|---|
committer | Joseph Birr-Pixton <jpixton@gmail.com> | 2017-05-06 18:23:30 +0100 |
commit | 14e9529e406065efe23f4de9112601d896820716 (patch) | |
tree | 2299d98c6ec22e988b0d0611d7dad2bc9b82c505 | |
parent | dac2274e80495888768ee3ff18df34891d12ba1e (diff) |
Update mio dependency to 0.6v/0.6.0
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | examples/tlsclient.rs | 64 | ||||
-rw-r--r-- | examples/tlsserver.rs | 158 |
3 files changed, 119 insertions, 105 deletions
@@ -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) + } + } + } } |