Add TcpListener::accept_std as a method

This should allow configuration over what reactor accepted streams go on to by
giving back a libstd-bound object that can then be used later in conjunction
with `TcpStream::from_std`.
This commit is contained in:
Alex Crichton 2017-12-05 08:48:17 -08:00
parent e86fc4917a
commit 2e58422890
2 changed files with 21 additions and 7 deletions

View File

@ -19,7 +19,7 @@ appveyor = { repository = "alexcrichton/tokio" }
[dependencies]
bytes = "0.4"
log = "0.3"
mio = "0.6.10"
mio = "0.6.11"
slab = "0.4"
iovec = "0.1"
tokio-io = "0.1"

View File

@ -57,21 +57,35 @@ impl TcpListener {
/// future's task. It's recommended to only call this from the
/// implementation of a `Future::poll`, if necessary.
pub fn accept(&mut self) -> io::Result<(TcpStream, SocketAddr)> {
let (stream, addr) = self.accept_std()?;
let stream = TcpStream::from_std(stream, self.io.handle())?;
Ok((stream, addr))
}
/// Attempt to accept a connection and create a new connected `TcpStream` if
/// successful.
///
/// This function is the asme as `accept` above except that it returns a
/// `std::net::TcpStream` instead of a `tokio::net::TcpStream`. This in turn
/// can then allow for the TCP stream to be assoiated with a different
/// reactor than the one this `TcpListener` is associated with.
///
/// # Panics
///
/// This function will panic for the same reasons as `accept`, notably if
/// called outside the context of a future.
pub fn accept_std(&mut self) -> io::Result<(net::TcpStream, SocketAddr)> {
if let Async::NotReady = self.io.poll_read() {
return Err(io::Error::new(io::ErrorKind::WouldBlock, "not ready"))
}
match self.io.get_ref().accept() {
match self.io.get_ref().accept_std() {
Ok(pair) => Ok(pair),
Err(e) => {
if e.kind() == io::ErrorKind::WouldBlock {
self.io.need_read()?;
}
Err(e)
},
Ok((sock, addr)) => {
let handle = self.io.handle();
let io = try!(PollEvented::new(sock, &handle));
Ok((TcpStream { io: io }, addr))
}
}
}