Re-work I/O

* Auto-register interest whenever we see WouldBlock
* Remove implementations of `Stream<Item=Ready>`, no longer needed
* Add explicit `poll_{read,write}` methods, if needed
* Remove all I/O streams, libstd ones suffice
* Update all I/O futures
This commit is contained in:
Alex Crichton
2016-08-17 18:41:34 -07:00
parent 293d104177
commit d0b911189c
13 changed files with 367 additions and 230 deletions
+2 -2
View File
@@ -5,11 +5,11 @@ extern crate env_logger;
use std::net::TcpStream;
use std::thread;
use std::io::{Read, Write};
use std::io::{Read, Write, BufReader, BufWriter};
use futures::Future;
use futures::stream::Stream;
use futures_io::{BufReader, BufWriter, copy};
use futures_io::copy;
macro_rules! t {
($e:expr) => (match $e {
+3 -5
View File
@@ -4,11 +4,11 @@ extern crate futures_mio;
use std::net::TcpStream;
use std::thread;
use std::io::Write;
use std::io::{Write, Read};
use futures::Future;
use futures::stream::Stream;
use futures_io::{chain, read_to_end};
use futures_io::read_to_end;
macro_rules! t {
($e:expr) => (match $e {
@@ -40,9 +40,7 @@ fn chain_clients() {
let b = clients.next().unwrap();
let c = clients.next().unwrap();
let d = chain(a, b);
let d = chain(d, c);
read_to_end(d, Vec::new())
read_to_end(a.chain(b).chain(c), Vec::new())
});
let data = t!(l.run(copied));
+28 -4
View File
@@ -3,13 +3,14 @@ extern crate futures;
extern crate futures_io;
extern crate futures_mio;
use std::net::TcpStream;
use std::io::{self, Read, Write};
use std::sync::Arc;
use std::thread;
use std::io::{Read, Write};
use futures::Future;
use futures::stream::Stream;
use futures_io::{copy, TaskIo};
use futures_io::copy;
use futures_mio::TcpStream;
macro_rules! t {
($e:expr) => (match $e {
@@ -29,6 +30,8 @@ fn echo_server() {
let msg = "foo bar baz";
let t = thread::spawn(move || {
use std::net::TcpStream;
let mut s = TcpStream::connect(&addr).unwrap();
for _i in 0..1024 {
@@ -41,7 +44,10 @@ fn echo_server() {
let clients = srv.incoming();
let client = clients.into_future().map(|e| e.0.unwrap()).map_err(|e| e.0);
let halves = client.and_then(|s| TaskIo::new(s.0)).map(|i| i.split());
let halves = client.map(|s| {
let s = Arc::new(s.0);
(SocketIo(s.clone()), SocketIo(s))
});
let copied = halves.and_then(|(a, b)| copy(a, b));
let amt = t!(l.run(copied));
@@ -49,3 +55,21 @@ fn echo_server() {
assert_eq!(amt, msg.len() as u64 * 1024);
}
struct SocketIo(Arc<TcpStream>);
impl Read for SocketIo {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
(&*self.0).read(buf)
}
}
impl Write for SocketIo {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
(&*self.0).write(buf)
}
fn flush(&mut self) -> io::Result<()> {
(&*self.0).flush()
}
}
+3 -3
View File
@@ -4,11 +4,11 @@ extern crate futures_mio;
use std::net::TcpStream;
use std::thread;
use std::io::Write;
use std::io::{Write, Read};
use futures::Future;
use futures::stream::Stream;
use futures_io::{read_to_end, take};
use futures_io::read_to_end;
macro_rules! t {
($e:expr) => (match $e {
@@ -34,7 +34,7 @@ fn limit() {
let mut clients = clients.into_iter();
let a = clients.next().unwrap();
read_to_end(take(a, 4), Vec::new())
read_to_end(a.take(4), Vec::new())
});
let data = t!(l.run(copied));
+27 -6
View File
@@ -3,13 +3,14 @@ extern crate futures_io;
extern crate futures_mio;
extern crate env_logger;
use std::net::TcpStream;
use std::sync::Arc;
use std::thread;
use std::io::{Read, Write};
use std::io::{self, Read, Write};
use futures::Future;
use futures::stream::Stream;
use futures_io::{copy, TaskIo};
use futures_io::copy;
use futures_mio::TcpStream;
macro_rules! t {
($e:expr) => (match $e {
@@ -28,6 +29,8 @@ fn echo_server() {
let addr = t!(srv.local_addr());
let t = thread::spawn(move || {
use std::net::TcpStream;
let mut s1 = t!(TcpStream::connect(&addr));
let mut s2 = t!(TcpStream::connect(&addr));
@@ -42,9 +45,9 @@ fn echo_server() {
});
let future = srv.incoming()
.and_then(|s| TaskIo::new(s.0))
.map(|i| i.split())
.map(|(a,b)| copy(a,b).map(|_| ()))
.map(|s| Arc::new(s.0))
.map(|i| (SocketIo(i.clone()), SocketIo(i)))
.map(|(a, b)| copy(a, b).map(|_| ()))
.buffered(10)
.take(2)
.collect();
@@ -53,3 +56,21 @@ fn echo_server() {
t.join().unwrap();
}
struct SocketIo(Arc<TcpStream>);
impl Read for SocketIo {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
(&*self.0).read(buf)
}
}
impl Write for SocketIo {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
(&*self.0).write(buf)
}
fn flush(&mut self) -> io::Result<()> {
(&*self.0).flush()
}
}
+51 -22
View File
@@ -1,8 +1,11 @@
extern crate futures;
extern crate futures_mio;
use futures::Future;
use futures::stream::Stream;
use std::io;
use std::net::SocketAddr;
use futures::{Future, Poll};
use futures_mio::UdpSocket;
macro_rules! t {
($e:expr) => (match $e {
@@ -20,24 +23,50 @@ fn send_messages() {
let a_addr = t!(a.local_addr());
let b_addr = t!(b.local_addr());
let ((ar, a), (br, b)) = t!(l.run(a.into_future().join(b.into_future())));
let ar = ar.unwrap();
let br = br.unwrap();
assert!(ar.is_write());
assert!(!ar.is_read());
assert!(br.is_write());
assert!(!br.is_read());
assert_eq!(t!(a.send_to(b"1234", &b_addr)), 4);
let (br, b) = t!(l.run(b.into_future()));
let br = br.unwrap();
assert!(br.is_read());
let mut buf = [0; 32];
let (size, addr) = t!(b.recv_from(&mut buf));
assert_eq!(size, 4);
assert_eq!(&buf[..4], b"1234");
assert_eq!(addr, a_addr);
let send = SendMessage { socket: a, addr: b_addr };
let recv = RecvMessage { socket: b, expected_addr: a_addr };
t!(l.run(send.join(recv)));
}
struct SendMessage {
socket: UdpSocket,
addr: SocketAddr,
}
impl Future for SendMessage {
type Item = ();
type Error = io::Error;
fn poll(&mut self) -> Poll<(), io::Error> {
match self.socket.send_to(b"1234", &self.addr) {
Ok(4) => Poll::Ok(()),
Ok(n) => panic!("didn't send 4 bytes: {}", n),
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Poll::NotReady,
Err(e) => Poll::Err(e),
}
}
}
struct RecvMessage {
socket: UdpSocket,
expected_addr: SocketAddr,
}
impl Future for RecvMessage {
type Item = ();
type Error = io::Error;
fn poll(&mut self) -> Poll<(), io::Error> {
let mut buf = [0; 32];
match self.socket.recv_from(&mut buf) {
Ok((4, addr)) => {
assert_eq!(&buf[..4], b"1234");
assert_eq!(addr, self.expected_addr);
Poll::Ok(())
}
Ok((n, _)) => panic!("didn't read 4 bytes: {}", n),
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Poll::NotReady,
Err(e) => Poll::Err(e),
}
}
}