Index: mojo/public/rust/src/system/data_pipe.rs |
diff --git a/mojo/public/rust/src/system/data_pipe.rs b/mojo/public/rust/src/system/data_pipe.rs |
deleted file mode 100644 |
index 23aa027dd29c9b21833fcd1b56fecfafd1f7b9ee..0000000000000000000000000000000000000000 |
--- a/mojo/public/rust/src/system/data_pipe.rs |
+++ /dev/null |
@@ -1,439 +0,0 @@ |
-// Copyright 2016 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-use std::marker; |
-use std::mem; |
-use std::ops; |
-use std::ptr; |
-use std::slice; |
-use std::vec; |
- |
-use system::ffi; |
-// This full import is intentional; nearly every type in mojo_types needs to be used. |
-use system::mojo_types::*; |
-use system::handle; |
-use system::handle::{CastHandle, Handle}; |
- |
-#[repr(u32)] |
-/// Create flags for data pipes |
-pub enum Create { |
- None = 0, |
-} |
- |
-#[repr(u32)] |
-/// Write flags for data pipes |
-pub enum Write { |
- None = 0, |
- |
- /// Write all the data to the pipe if possible or none at all |
- AllOrNone = 1 << 0, |
-} |
- |
-#[repr(u32)] |
-/// Read flags for data pipes |
-pub enum Read { |
- None = 0, |
- |
- /// Read all the data from the pipe if possible, or none at all |
- AllOrNone = 1 << 0, |
- |
- /// Dequeue the message recieved rather than reading it |
- Discard = 1 << 1, |
- |
- /// Get information about the queue on the pipe but do not perform the |
- /// read |
- Query = 1 << 2, |
- |
- /// Read data off the pipe's queue but do not dequeue it |
- Peek = 1 << 3, |
-} |
- |
-/// Intermediary structure in a two-phase read. |
-/// Reads of the requested buffer must be done directly |
-/// through this data structure which must then be committed. |
-pub struct ReadDataBuffer<'b, 'p, T> |
- where 'p: 'b, |
- T: 'p |
-{ |
- buffer: &'b [T], |
- |
- /// Contains a reference to parent to end commit |
- /// and prevent it from outliving its parent handle. |
- parent: &'p Consumer<T>, |
-} |
- |
-impl<'b, 'p, T> ReadDataBuffer<'b, 'p, T> |
- where 'p: 'b, |
- T: 'p |
-{ |
- /// Attempts to commit the read, that is, end the two-phase read |
- /// started by the parent Consumer<T> object. On a successful |
- /// commit, consumes self, otherwise returns self to try again. |
- pub fn commit(self, bytes_read: usize) -> Option<(Self, MojoResult)> { |
- let result = unsafe { self.parent.end_read(bytes_read) }; |
- if result == MojoResult::Okay { |
- None |
- } else { |
- Some((self, result)) |
- } |
- } |
- |
- /// Returns the length of the underlying buffer |
- pub fn len(&self) -> usize { |
- self.buffer.len() |
- } |
-} |
- |
-impl<'b, 'p, T> ops::Index<usize> for ReadDataBuffer<'b, 'p, T> |
- where 'p: 'b, |
- T: 'p |
-{ |
- type Output = T; |
- |
- /// Overloads the indexing ([]) operator for reads. |
- /// |
- /// Part of reimplementing the array interface to be |
- /// able to use the structure naturally. |
- fn index(&self, index: usize) -> &T { |
- &self.buffer[index] |
- } |
-} |
- |
-/// Intermediary structure in a two-phase write. |
-/// Writes to the requested buffer must be done directly |
-/// through this data structure which must then be committed. |
-pub struct WriteDataBuffer<'b, 'p, T> |
- where 'p: 'b, |
- T: 'p |
-{ |
- buffer: &'b mut [T], |
- |
- /// Contains a reference to parent to end commit |
- /// and prevent it from outliving its parent handle. |
- parent: &'p Producer<T>, |
-} |
- |
-impl<'b, 'p, T> WriteDataBuffer<'b, 'p, T> |
- where 'p: 'b, |
- T: 'p |
-{ |
- /// Attempts to commit the write, that is, end the two-phase |
- /// write started by a Producer. On a successful |
- /// commit, consumes self, otherwise returns self to try again. |
- pub fn commit(self, bytes_written: usize) -> Option<(Self, MojoResult)> { |
- let result = unsafe { self.parent.end_write(bytes_written) }; |
- if result == MojoResult::Okay { |
- None |
- } else { |
- Some((self, result)) |
- } |
- } |
- |
- /// Returns the length of the underlying buffer |
- pub fn len(&self) -> usize { |
- self.buffer.len() |
- } |
-} |
- |
-impl<'b, 'p, T> ops::Index<usize> for WriteDataBuffer<'b, 'p, T> |
- where 'p: 'b, |
- T: 'p |
-{ |
- type Output = T; |
- |
- /// Overloads the indexing ([]) operator for reads. |
- /// |
- /// Part of reimplementing the array interface to be |
- /// able to use the structure naturally. |
- fn index(&self, index: usize) -> &T { |
- &self.buffer[index] |
- } |
-} |
- |
-impl<'b, 'p, T> ops::IndexMut<usize> for WriteDataBuffer<'b, 'p, T> |
- where 'p: 'b, |
- T: 'p |
-{ |
- /// Overloads the indexing ([]) operator for writes. |
- /// |
- /// Part of reimplementing the array interface to be |
- /// able to use the structure naturally. |
- fn index_mut(&mut self, index: usize) -> &mut T { |
- &mut self.buffer[index] |
- } |
-} |
- |
-/// Creates a data pipe, represented as a consumer |
-/// and a producer. Additionally, we associate a type |
-/// T with the data pipe, as data pipes operate in terms |
-/// of elements. In this way we can enforce type safety. |
-/// |
-/// Capacity, as an input, must be given in number of elements. |
-/// Use a capacity of 0 in order to use some system-dependent |
-/// default capacity. |
-pub fn create<T>(flags: CreateFlags, |
- capacity: u32) |
- -> Result<(Consumer<T>, Producer<T>), MojoResult> { |
- let elem_size = mem::size_of::<T>() as u32; |
- let opts = ffi::MojoCreateDataPipeOptions { |
- struct_size: mem::size_of::<ffi::MojoCreateDataPipeOptions>() as u32, |
- flags: flags, |
- element_num_bytes: elem_size, |
- capacity_num_bytes: capacity * elem_size, |
- _align: [], |
- }; |
- // TODO(mknyszek): Make sure handles are valid |
- let mut chandle: MojoHandle = 0; |
- let mut phandle: MojoHandle = 0; |
- let raw_opts = &opts as *const ffi::MojoCreateDataPipeOptions; |
- let r = MojoResult::from_code(unsafe { |
- ffi::MojoCreateDataPipe(raw_opts, |
- &mut phandle as *mut MojoHandle, |
- &mut chandle as *mut MojoHandle) |
- }); |
- if r != MojoResult::Okay { |
- Err(r) |
- } else { |
- Ok((Consumer::<T> { |
- handle: unsafe { handle::acquire(chandle) }, |
- _elem_type: marker::PhantomData, |
- }, |
- Producer::<T> { |
- handle: unsafe { handle::acquire(phandle) }, |
- _elem_type: marker::PhantomData, |
- })) |
- } |
-} |
- |
-/// Creates a data pipe, represented as a consumer |
-/// and a producer, using the default Mojo options. |
-pub fn create_default() -> Result<(Consumer<u8>, Producer<u8>), MojoResult> { |
- create::<u8>(Create::None as u32, 0) |
-} |
- |
-/// Represents the consumer half of a data pipe. |
-/// This data structure wraps a handle and acts |
-/// effectively as a typed handle. |
-/// |
-/// The purpose of the _elem_type field is to associate |
-/// a type with the consumer, as a data pipe works |
-/// in elements. |
-pub struct Consumer<T> { |
- handle: handle::UntypedHandle, |
- _elem_type: marker::PhantomData<T>, |
-} |
- |
-impl<T> Consumer<T> { |
- /// Perform a read operation on the consumer end of the data pipe. As |
- /// a result, we get an std::vec::Vec filled with whatever was written. |
- pub fn read(&self, flags: ReadFlags) -> Result<vec::Vec<T>, MojoResult> { |
- let mut num_bytes: u32 = 0; |
- let r_prelim = unsafe { |
- ffi::MojoReadData(self.handle.get_native_handle(), |
- ptr::null_mut() as *mut ffi::c_void, |
- &mut num_bytes as *mut u32, |
- 1 << 2 as ReadFlags) |
- }; |
- if r_prelim != 0 || num_bytes == 0 { |
- return Err(MojoResult::from_code(r_prelim)); |
- } |
- let elem_size: u32 = mem::size_of::<T>() as u32; |
- // TODO(mknyszek): make sure elem_size divides into num_bytes |
- let mut buf: vec::Vec<T> = vec::Vec::with_capacity((num_bytes / elem_size) as usize); |
- let r = MojoResult::from_code(unsafe { |
- ffi::MojoReadData(self.handle.get_native_handle(), |
- buf.as_mut_ptr() as *const ffi::c_void, |
- &mut num_bytes as *mut u32, |
- flags) |
- }); |
- unsafe { buf.set_len((num_bytes / elem_size) as usize) } |
- if r != MojoResult::Okay { |
- Err(r) |
- } else { |
- Ok(buf) |
- } |
- } |
- |
- /// Start two-phase read and return a ReadDataBuffer to perform |
- /// read and commit. |
- pub fn begin(&self, flags: ReadFlags) -> Result<ReadDataBuffer<T>, MojoResult> { |
- let wrapped_result = unsafe { self.begin_read(flags) }; |
- match wrapped_result { |
- Ok(arr) => { |
- Ok(ReadDataBuffer::<T> { |
- buffer: arr, |
- parent: self, |
- }) |
- } |
- Err(r) => Err(r), |
- } |
- } |
- |
- /// A private function that performs the first half of two-phase reading. |
- /// Kept private because it is unsafe to use (the array received may not |
- /// be valid if end_read is performed). |
- unsafe fn begin_read(&self, flags: ReadFlags) -> Result<&[T], MojoResult> { |
- let mut buf_num_bytes: u32 = 0; |
- let mut pbuf: *mut ffi::c_void = mem::uninitialized(); |
- let r = MojoResult::from_code(ffi::MojoBeginReadData(self.handle.get_native_handle(), |
- &mut pbuf, |
- &mut buf_num_bytes as *mut u32, |
- flags)); |
- if r != MojoResult::Okay { |
- Err(r) |
- } else { |
- let buf_elems = (buf_num_bytes as usize) / mem::size_of::<T>(); |
- let buf = slice::from_raw_parts(pbuf as *mut T, buf_elems); |
- Ok(buf) |
- } |
- } |
- |
- /// A private function that performs the second half of two-phase reading. |
- /// Kept private because it is unsafe to use (the array received from start_read |
- /// may not be valid if end_read is performed). |
- /// |
- /// Also assumes loads/stores aren't reordered such that a load/store may be |
- /// optimized to be run AFTER MojoEndReadData(). In general, this is true as long |
- /// as raw pointers are used, but Rust's memory model is still undefined. If you're |
- /// getting a bad/strange runtime error, it might be for this reason. |
- unsafe fn end_read(&self, elems_read: usize) -> MojoResult { |
- let elem_size = mem::size_of::<T>(); |
- MojoResult::from_code(ffi::MojoEndReadData(self.handle.get_native_handle(), |
- (elems_read * elem_size) as u32)) |
- } |
-} |
- |
-impl<T> CastHandle for Consumer<T> { |
- /// Generates a Consumer from an untyped handle wrapper |
- /// See mojo::system::handle for information on untyped vs. typed |
- unsafe fn from_untyped(handle: handle::UntypedHandle) -> Self { |
- Consumer::<T> { |
- handle: handle, |
- _elem_type: marker::PhantomData, |
- } |
- } |
- |
- /// Consumes this object and produces a plain handle wrapper |
- /// See mojo::system::handle for information on untyped vs. typed |
- fn as_untyped(self) -> handle::UntypedHandle { |
- self.handle |
- } |
-} |
- |
-impl<T> Handle for Consumer<T> { |
- /// Returns the native handle wrapped by this structure. |
- /// |
- /// See mojo::system::handle for information on handle wrappers |
- fn get_native_handle(&self) -> MojoHandle { |
- self.handle.get_native_handle() |
- } |
-} |
- |
-/// Represents the consumer half of a data pipe. |
-/// This data structure wraps a handle and acts |
-/// effectively as a typed handle. |
-/// |
-/// The purpose of the _elem_type field is to associate |
-/// a type with the consumer, as a data pipe works |
-/// in elements. |
-pub struct Producer<T> { |
- handle: handle::UntypedHandle, |
- _elem_type: marker::PhantomData<T>, |
-} |
- |
-impl<T> Producer<T> { |
- /// Perform a write operation on the producer end of the data pipe. |
- /// Returns the number of elements actually written. |
- pub fn write(&self, data: &[T], flags: WriteFlags) -> Result<usize, MojoResult> { |
- let mut num_bytes = (data.len() * mem::size_of::<T>()) as u32; |
- let r = MojoResult::from_code(unsafe { |
- ffi::MojoWriteData(self.handle.get_native_handle(), |
- data.as_ptr() as *const ffi::c_void, |
- &mut num_bytes as *mut u32, |
- flags) |
- }); |
- if r != MojoResult::Okay { |
- Err(r) |
- } else { |
- Ok(num_bytes as usize) |
- } |
- } |
- |
- /// Start two-phase write and return a WriteDataBuffer to perform |
- /// write and commit. |
- /// |
- /// Borrows self as mutable so that no other operation may happen on |
- /// the producer until the two-phase write is committed. |
- pub fn begin(&self, flags: WriteFlags) -> Result<WriteDataBuffer<T>, MojoResult> { |
- let wrapped_result = unsafe { self.begin_write(flags) }; |
- match wrapped_result { |
- Ok(arr) => { |
- Ok(WriteDataBuffer::<T> { |
- buffer: arr, |
- parent: self, |
- }) |
- } |
- Err(r) => Err(r), |
- } |
- } |
- |
- /// A private function that performs the first half of two-phase writing. |
- /// Kept private because it is unsafe to use (the array received may not |
- /// be valid if end_write is performed). |
- unsafe fn begin_write(&self, flags: WriteFlags) -> Result<&mut [T], MojoResult> { |
- let mut buf_num_bytes: u32 = 0; |
- let mut pbuf: *mut ffi::c_void = mem::uninitialized(); |
- let r = MojoResult::from_code(ffi::MojoBeginWriteData(self.handle.get_native_handle(), |
- &mut pbuf, |
- &mut buf_num_bytes as *mut u32, |
- flags)); |
- if r != MojoResult::Okay { |
- Err(r) |
- } else { |
- let buf_elems = (buf_num_bytes as usize) / mem::size_of::<T>(); |
- let buf = slice::from_raw_parts_mut(pbuf as *mut T, buf_elems); |
- Ok(buf) |
- } |
- } |
- |
- /// A private function that performs the second half of two-phase writing. |
- /// Kept private because it is unsafe to use (the array received from start_write |
- /// may not be valid if end_write is performed). |
- /// |
- /// Also assumes loads/stores aren't reordered such that a load/store may be |
- /// optimized to be run AFTER MojoEndWriteData(). In general, this is true as long |
- /// as raw pointers are used, but Rust's memory model is still undefined. If you're |
- /// getting a bad/strange runtime error, it might be for this reason. |
- unsafe fn end_write(&self, elems_written: usize) -> MojoResult { |
- let elem_size = mem::size_of::<T>(); |
- MojoResult::from_code(ffi::MojoEndWriteData(self.handle.get_native_handle(), |
- (elems_written * elem_size) as u32)) |
- } |
-} |
- |
-impl<T> CastHandle for Producer<T> { |
- /// Generates a Consumer from an untyped handle wrapper |
- /// See mojo::system::handle for information on untyped vs. typed |
- unsafe fn from_untyped(handle: handle::UntypedHandle) -> Self { |
- Producer::<T> { |
- handle: handle, |
- _elem_type: marker::PhantomData, |
- } |
- } |
- |
- /// Consumes this object and produces a plain handle wrapper |
- /// See mojo::system::handle for information on untyped vs. typed |
- fn as_untyped(self) -> handle::UntypedHandle { |
- self.handle |
- } |
-} |
- |
-impl<T> Handle for Producer<T> { |
- /// Returns the native handle wrapped by this structure. |
- /// |
- /// See mojo::system::handle for information on handle wrappers |
- fn get_native_handle(&self) -> MojoHandle { |
- self.handle.get_native_handle() |
- } |
-} |