Swap Handle/Pinned

* Handle -> Remote
* Pinned -> Handle

All APIs now take a `&Handle` by default and in general can return an immediate
`io::Result` instead of an `IoFuture`. This reflects how most usage will likely
be done through handles rather than remotes, and also all previous functionality
can be recovered with a `oneshot` plus `Remote::spawn`.

Closes #15
This commit is contained in:
Alex Crichton
2016-09-07 22:12:41 -07:00
parent e60002b653
commit 66cff8e84b
23 changed files with 327 additions and 1344 deletions
+22 -36
View File
@@ -4,7 +4,7 @@ use std::mem;
use std::net::{self, SocketAddr, Shutdown};
use futures::stream::Stream;
use futures::{Future, IntoFuture, failed, Poll, Async};
use futures::{self, Future, failed, Poll, Async};
use mio;
use io::{Io, IoFuture, IoStream};
@@ -18,11 +18,6 @@ pub struct TcpListener {
io: PollEvented<mio::tcp::TcpListener>,
}
/// Future which will resolve to a `TcpListener`
pub struct TcpListenerNew {
inner: IoFuture<TcpListener>,
}
/// Stream returned by the `TcpListener::incoming` function representing the
/// stream of sockets received from a listener.
pub struct Incoming {
@@ -35,12 +30,9 @@ impl TcpListener {
/// The TCP listener will bind to the provided `addr` address, if available,
/// and will be returned as a future. The returned future, if resolved
/// successfully, can then be used to accept incoming connections.
pub fn bind(addr: &SocketAddr, handle: &Handle) -> TcpListenerNew {
let future = match mio::tcp::TcpListener::bind(addr) {
Ok(l) => TcpListener::new(l, handle),
Err(e) => failed(e).boxed(),
};
TcpListenerNew { inner: future }
pub fn bind(addr: &SocketAddr, handle: &Handle) -> io::Result<TcpListener> {
let l = try!(mio::tcp::TcpListener::bind(addr));
TcpListener::new(l, handle)
}
/// Create a new TCP listener from the standard library's TCP listener.
@@ -72,19 +64,15 @@ impl TcpListener {
/// well (same for IPv6).
pub fn from_listener(listener: net::TcpListener,
addr: &SocketAddr,
handle: &Handle) -> IoFuture<TcpListener> {
let handle = handle.clone();
mio::tcp::TcpListener::from_listener(listener, addr)
.into_future()
.and_then(move |l| TcpListener::new(l, &handle))
.boxed()
handle: &Handle) -> io::Result<TcpListener> {
let l = try!(mio::tcp::TcpListener::from_listener(listener, addr));
TcpListener::new(l, handle)
}
fn new(listener: mio::tcp::TcpListener, handle: &Handle)
-> IoFuture<TcpListener> {
PollEvented::new(listener, handle).map(|io| {
TcpListener { io: io }
}).boxed()
-> io::Result<TcpListener> {
let io = try!(PollEvented::new(listener, handle));
Ok(TcpListener { io: io })
}
/// Test whether this socket is ready to be read or not.
@@ -129,13 +117,19 @@ impl TcpListener {
}
}
let handle = self.io.handle().clone();
let remote = self.io.remote().clone();
let stream = MyIncoming { inner: self };
Incoming {
inner: stream.and_then(move |(tcp, addr)| {
PollEvented::new(tcp, &handle).map(move |io| {
(TcpStream { io: io }, addr)
})
let (tx, rx) = futures::oneshot();
remote.spawn(move |handle| {
let res = PollEvented::new(tcp, handle).map(move |io| {
(TcpStream { io: io }, addr)
});
tx.complete(res);
Ok(())
});
rx.then(|r| r.expect("shouldn't be canceled"))
}).boxed(),
}
}
@@ -185,15 +179,6 @@ impl fmt::Debug for TcpListener {
}
}
impl Future for TcpListenerNew {
type Item = TcpListener;
type Error = io::Error;
fn poll(&mut self) -> Poll<TcpListener, io::Error> {
self.inner.poll()
}
}
impl Stream for Incoming {
type Item = (TcpStream, SocketAddr);
type Error = io::Error;
@@ -242,7 +227,8 @@ impl TcpStream {
fn new(connected_stream: mio::tcp::TcpStream, handle: &Handle)
-> IoFuture<TcpStream> {
PollEvented::new(connected_stream, handle).and_then(|io| {
let tcp = PollEvented::new(connected_stream, handle);
futures::done(tcp).and_then(|io| {
TcpStreamConnect::Waiting(TcpStream { io: io })
}).boxed()
}