mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-10-01 12:20:39 +00:00
add read_bufs and write_bufs to Io and TcpStream
This commit is contained in:
parent
a4b4d57cb7
commit
829563ccfc
@ -14,6 +14,8 @@ use std::io;
|
||||
use futures::{BoxFuture, Async, Poll};
|
||||
use futures::stream::BoxStream;
|
||||
|
||||
use mio::IoVec;
|
||||
|
||||
/// A convenience typedef around a `Future` whose error component is `io::Error`
|
||||
pub type IoFuture<T> = BoxFuture<T, io::Error>;
|
||||
|
||||
@ -114,6 +116,57 @@ pub trait Io: io::Read + io::Write {
|
||||
Async::Ready(())
|
||||
}
|
||||
|
||||
/// Read in a list of buffers all at once.
|
||||
///
|
||||
/// This operation will attempt to read bytes from this socket and place
|
||||
/// them into the list of buffers provided. Note that each buffer is an
|
||||
/// `IoVec` which can be created from a byte slice.
|
||||
///
|
||||
/// The buffers provided will be filled in sequentially. A buffer will be
|
||||
/// entirely filled up before the next is written to.
|
||||
///
|
||||
/// The number of bytes read is returned, if successful, or an error is
|
||||
/// returned otherwise. If no bytes are available to be read yet then
|
||||
/// a "would block" error is returned. This operation should not block.
|
||||
///
|
||||
/// There is a default implementation for this function which treats this
|
||||
/// as a single read using the first buffer in the list, but objects which
|
||||
/// can implement this as an atomic read using all the buffers are
|
||||
/// recommended to do so. For example, `TcpStream` can implement this
|
||||
/// using the `readv` syscall.
|
||||
fn read_vec(&mut self, bufs: &mut [&mut IoVec]) -> io::Result<usize> {
|
||||
if bufs.is_empty() {
|
||||
Ok(0)
|
||||
} else {
|
||||
self.read(bufs[0].as_mut_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
/// Write a list of buffers all at once.
|
||||
///
|
||||
/// This operation will attempt to write a list of byte buffers to this
|
||||
/// socket. Note that each buffer is an `IoVec` which can be created from a
|
||||
/// byte slice.
|
||||
///
|
||||
/// The buffers provided will be written sequentially. A buffer will be
|
||||
/// entirely written before the next is written.
|
||||
///
|
||||
/// The number of bytes written is returned, if successful, or an error is
|
||||
/// returned otherwise. If the socket is not currently writable then a
|
||||
/// "would block" error is returned. This operation should not block.
|
||||
///
|
||||
/// There is a default implementation for this function which writes the
|
||||
/// first buffer only, but objects which can implement this as an atomic
|
||||
/// write using all the buffers are recommended to do so. For example,
|
||||
/// `TcpStream` can implement this using the `writev` syscall.
|
||||
fn write_vec(&mut self, bufs: &[&IoVec]) -> io::Result<usize> {
|
||||
if bufs.is_empty() {
|
||||
Ok(0)
|
||||
} else {
|
||||
self.write(bufs[0].as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides a `Stream` and `Sink` interface for reading and writing to this
|
||||
/// `Io` object, using `Decode` and `Encode` to read and write the raw data.
|
||||
///
|
||||
|
@ -433,6 +433,38 @@ impl Io for TcpStream {
|
||||
fn poll_write(&mut self) -> Async<()> {
|
||||
<TcpStream>::poll_write(self)
|
||||
}
|
||||
|
||||
fn read_vec(&mut self, bufs: &mut [&mut mio::IoVec]) -> io::Result<usize> {
|
||||
if let Async::NotReady = self.poll_read() {
|
||||
return Err(mio::would_block())
|
||||
}
|
||||
let r = self.io.get_ref().read_bufs(bufs);
|
||||
if is_wouldblock(&r) {
|
||||
self.io.need_read();
|
||||
}
|
||||
return r
|
||||
|
||||
|
||||
}
|
||||
|
||||
fn write_vec(&mut self, bufs: &[&mio::IoVec]) -> io::Result<usize> {
|
||||
if let Async::NotReady = self.poll_write() {
|
||||
return Err(mio::would_block())
|
||||
}
|
||||
let r = self.io.get_ref().write_bufs(bufs);
|
||||
if is_wouldblock(&r) {
|
||||
self.io.need_write();
|
||||
}
|
||||
return r
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fn is_wouldblock<T>(r: &io::Result<T>) -> bool {
|
||||
match *r {
|
||||
Ok(_) => false,
|
||||
Err(ref e) => e.kind() == io::ErrorKind::WouldBlock,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Read for &'a TcpStream {
|
||||
|
Loading…
x
Reference in New Issue
Block a user