diff --git a/examples/echo.rs b/examples/echo.rs index 4c8417c8f..4f46e5fc8 100644 --- a/examples/echo.rs +++ b/examples/echo.rs @@ -9,7 +9,7 @@ use std::net::SocketAddr; use futures::Future; use futures::stream::Stream; -use tokio_core::io::{copy, TaskIo}; +use tokio_core::io::{copy, Io}; use tokio_core::net::TcpListener; use tokio_core::reactor::Core; @@ -35,8 +35,7 @@ fn main() { // We use the `io::copy` future to copy all data from the // reading half onto the writing half. socket.incoming().for_each(move |(socket, addr)| { - let socket = futures::lazy(|| futures::finished(TaskIo::new(socket))); - let pair = socket.map(|s| s.split()); + let pair = futures::lazy(|| futures::finished(socket.split())); let amt = pair.and_then(|(reader, writer)| copy(reader, writer)); // Once all that is done we print out how much we wrote, and then diff --git a/src/io/mod.rs b/src/io/mod.rs index a9f3a8f2e..0594c54ea 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -35,14 +35,14 @@ mod copy; mod flush; mod read_exact; mod read_to_end; -mod task; +mod split; mod window; mod write_all; pub use self::copy::{copy, Copy}; pub use self::flush::{flush, Flush}; pub use self::read_exact::{read_exact, ReadExact}; pub use self::read_to_end::{read_to_end, ReadToEnd}; -pub use self::task::{TaskIo, TaskIoRead, TaskIoWrite}; +pub use self::split::{ReadHalf, WriteHalf}; pub use self::window::Window; pub use self::write_all::{write_all, WriteAll}; @@ -110,9 +110,9 @@ pub trait Io: Read + Write { /// # Panics /// /// This method will panic if there is not currently an active future task. - fn task_split(self) -> (TaskIoRead, TaskIoWrite) + fn split(self) -> (ReadHalf, WriteHalf) where Self: Sized { - TaskIo::new(self).split() + split::split(self) } } diff --git a/src/io/split.rs b/src/io/split.rs new file mode 100644 index 000000000..fe8071de7 --- /dev/null +++ b/src/io/split.rs @@ -0,0 +1,35 @@ +use std::cell::RefCell; +use std::io::{self, Read, Write}; + +use futures::task::TaskRc; + +/// The readable half of an object returned from `Io::split`. +pub struct ReadHalf { + handle: TaskRc>, +} + +/// The readable half of an object returned from `Io::split`. +pub struct WriteHalf { + handle: TaskRc>, +} + +pub fn split(t: T) -> (ReadHalf, WriteHalf) { + let rc = TaskRc::new(RefCell::new(t)); + (ReadHalf { handle: rc.clone() }, WriteHalf { handle: rc }) +} + +impl Read for ReadHalf { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.handle.with(|t| t.borrow_mut().read(buf)) + } +} + +impl Write for WriteHalf { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.handle.with(|t| t.borrow_mut().write(buf)) + } + + fn flush(&mut self) -> io::Result<()> { + self.handle.with(|t| t.borrow_mut().flush()) + } +} diff --git a/src/io/task.rs b/src/io/task.rs deleted file mode 100644 index e7b42a49f..000000000 --- a/src/io/task.rs +++ /dev/null @@ -1,102 +0,0 @@ -use std::cell::RefCell; -use std::io::{self, Read, Write}; - -use futures::task::TaskRc; - -/// Abstraction that allows inserting an I/O object into task-local storage, -/// returning a handle that can be split. -/// -/// A `TaskIo` handle implements the `ReadTask` and `WriteTask` and will only -/// work with the same task that the associated object was inserted into. The -/// handle may then be optionally `split` into the read/write halves so they can -/// be worked with independently. -/// -/// Note that it is important that the future returned from `TaskIo::new`, when -/// polled, will pin the yielded `TaskIo` object to that specific task. Any -/// attempt to read or write the object on other tasks will result in a panic. -pub struct TaskIo { - handle: TaskRc>, -} - -/// The readable half of a `TaskIo` instance returned from `TaskIo::split`. -/// -/// This handle implements the `ReadTask` trait and can be used to split up an -/// I/O object into two distinct halves. -pub struct TaskIoRead { - handle: TaskRc>, -} - -/// The writable half of a `TaskIo` instance returned from `TaskIo::split`. -/// -/// This handle implements the `WriteTask` trait and can be used to split up an -/// I/O object into two distinct halves. -pub struct TaskIoWrite { - handle: TaskRc>, -} - -impl TaskIo { - /// Returns a new future which represents the insertion of the I/O object - /// `T` into task local storage, returning a `TaskIo` handle to it. - /// - /// The returned future will never resolve to an error. - pub fn new(t: T) -> TaskIo { - TaskIo { - handle: TaskRc::new(RefCell::new(t)), - } - } -} - -impl TaskIo - where T: Read + Write, -{ - /// For an I/O object which is both readable and writable, this method can - /// be used to split the handle into two independently owned halves. - /// - /// The returned pair implements the `ReadTask` and `WriteTask` traits, - /// respectively, and can be used to pass around the object to different - /// combinators if necessary. - pub fn split(self) -> (TaskIoRead, TaskIoWrite) { - (TaskIoRead { handle: self.handle.clone() }, - TaskIoWrite { handle: self.handle }) - } -} - -impl Read for TaskIo - where T: io::Read, -{ - fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.handle.with(|t| t.borrow_mut().read(buf)) - } -} - -impl Write for TaskIo - where T: io::Write, -{ - fn write(&mut self, buf: &[u8]) -> io::Result { - self.handle.with(|t| t.borrow_mut().write(buf)) - } - - fn flush(&mut self) -> io::Result<()> { - self.handle.with(|t| t.borrow_mut().flush()) - } -} - -impl Read for TaskIoRead - where T: io::Read, -{ - fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.handle.with(|t| t.borrow_mut().read(buf)) - } -} - -impl Write for TaskIoWrite - where T: io::Write, -{ - fn write(&mut self, buf: &[u8]) -> io::Result { - self.handle.with(|t| t.borrow_mut().write(buf)) - } - - fn flush(&mut self) -> io::Result<()> { - self.handle.with(|t| t.borrow_mut().flush()) - } -} diff --git a/src/lib.rs b/src/lib.rs index c31e15043..737765550 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,7 +73,7 @@ //! // We use the `io::copy` future to copy all data from the //! // reading half onto the writing half. //! socket.incoming().for_each(|(socket, addr)| { -//! let pair = futures::lazy(|| Ok(socket.task_split())); +//! let pair = futures::lazy(|| Ok(socket.split())); //! let amt = pair.and_then(|(reader, writer)| copy(reader, writer)); //! //! // Once all that is done we print out how much we wrote, and then diff --git a/tests/echo.rs b/tests/echo.rs index a7a85a4c9..3d661a8b5 100644 --- a/tests/echo.rs +++ b/tests/echo.rs @@ -8,7 +8,7 @@ use std::thread; use futures::Future; use futures::stream::Stream; -use tokio_core::io::{copy, TaskIo}; +use tokio_core::io::{copy, Io}; use tokio_core::net::TcpListener; use tokio_core::reactor::Core; @@ -42,7 +42,7 @@ 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.map(|s| TaskIo::new(s.0).split()); + let halves = client.map(|s| s.0.split()); let copied = halves.and_then(|(a, b)| copy(a, b)); let amt = t!(l.run(copied)); diff --git a/tests/stream-buffered.rs b/tests/stream-buffered.rs index b63618deb..6465b9950 100644 --- a/tests/stream-buffered.rs +++ b/tests/stream-buffered.rs @@ -8,7 +8,7 @@ use std::thread; use futures::Future; use futures::stream::Stream; -use tokio_core::io::{copy, TaskIo}; +use tokio_core::io::{Io, copy}; use tokio_core::net::TcpListener; use tokio_core::reactor::Core; @@ -43,7 +43,7 @@ fn echo_server() { }); let future = srv.incoming() - .map(|s| TaskIo::new(s.0).split()) + .map(|s| s.0.split()) .map(|(a, b)| copy(a, b).map(|_| ())) .buffered(10) .take(2)