From f107c8d860137b41e509b179d605db30082cb0da Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 26 Aug 2016 14:30:46 -0700 Subject: Rename to tokio-core, add in futures-io Renames the futures-mio crate to tokio-core, pulls in the futures-io crate under an `io` module, and gets everything compiling. --- src/io/task.rs | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/io/task.rs (limited to 'src/io/task.rs') diff --git a/src/io/task.rs b/src/io/task.rs new file mode 100644 index 00000000..3c87a32e --- /dev/null +++ b/src/io/task.rs @@ -0,0 +1,102 @@ +use std::cell::RefCell; +use std::io::{self, Read, Write}; + +use futures::task::TaskData; + +/// 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: TaskData>, +} + +/// 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: TaskData>, +} + +/// 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: TaskData>, +} + +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: TaskData::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()) + } +} -- cgit v1.2.3