| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 use std::mem; | |
| 6 use std::vec; | |
| 7 use std::ptr; | |
| 8 | |
| 9 use system::ffi; | |
| 10 use system::handle; | |
| 11 use system::handle::{CastHandle, Handle}; | |
| 12 // This full import is intentional; nearly every type in mojo_types needs to be
used. | |
| 13 use system::mojo_types::*; | |
| 14 | |
| 15 #[repr(u32)] | |
| 16 /// Create flags for message pipes | |
| 17 pub enum Create { | |
| 18 None = 0, | |
| 19 } | |
| 20 | |
| 21 #[repr(u32)] | |
| 22 /// Write flags for message pipes | |
| 23 pub enum Write { | |
| 24 None = 0, | |
| 25 } | |
| 26 | |
| 27 #[repr(u32)] | |
| 28 /// Read flags for message pipes | |
| 29 pub enum Read { | |
| 30 None = 0, | |
| 31 | |
| 32 /// If the message is unable to be | |
| 33 /// read for whatever reason, dequeue | |
| 34 /// it anyway | |
| 35 MayDiscard = 1 << 0, | |
| 36 } | |
| 37 | |
| 38 /// Creates a message pipe in Mojo and gives back two | |
| 39 /// MessageEndpoints which represent the endpoints of the | |
| 40 /// message pipe | |
| 41 pub fn create(flags: CreateFlags) -> Result<(MessageEndpoint, MessageEndpoint),
MojoResult> { | |
| 42 let mut handle0: MojoHandle = 0; | |
| 43 let mut handle1: MojoHandle = 0; | |
| 44 let opts = ffi::MojoCreateMessagePipeOptions { | |
| 45 struct_size: mem::size_of::<ffi::MojoCreateMessagePipeOptions>() as u32, | |
| 46 flags: flags, | |
| 47 _align: [], | |
| 48 }; | |
| 49 let raw_opts = &opts as *const ffi::MojoCreateMessagePipeOptions; | |
| 50 let r = MojoResult::from_code(unsafe { | |
| 51 ffi::MojoCreateMessagePipe(raw_opts, | |
| 52 &mut handle0 as *mut MojoHandle, | |
| 53 &mut handle1 as *mut MojoHandle) | |
| 54 }); | |
| 55 if r != MojoResult::Okay { | |
| 56 Err(r) | |
| 57 } else { | |
| 58 Ok((MessageEndpoint { handle: unsafe { handle::acquire(handle0) } }, | |
| 59 MessageEndpoint { handle: unsafe { handle::acquire(handle1) } })) | |
| 60 } | |
| 61 } | |
| 62 | |
| 63 /// Represents the one endpoint of a message pipe. | |
| 64 /// This data structure wraps a handle and acts | |
| 65 /// effectively as a typed handle. | |
| 66 pub struct MessageEndpoint { | |
| 67 handle: handle::UntypedHandle, | |
| 68 } | |
| 69 | |
| 70 impl MessageEndpoint { | |
| 71 /// Read the next message from the endpoint. Messages in Mojo | |
| 72 /// are some set of bytes plus a bunch of handles, so we | |
| 73 /// return both a vector of bytes and a vector of untyped handles. | |
| 74 /// | |
| 75 /// Because the handles are untyped, it is up to the user of this | |
| 76 /// library to know what type the handle actually is and to use | |
| 77 /// from_untyped in order to convert the handle to the correct type. | |
| 78 /// This is abstracted away, however, when using the Mojo bindings | |
| 79 /// generator where you may specify your interface in Mojom. | |
| 80 /// | |
| 81 /// If an empty message (that is, it has neither data nor handles) | |
| 82 /// is received, it will show up as an Err() containing MojoResult::Okay. | |
| 83 pub fn read(&self, | |
| 84 flags: ReadFlags) | |
| 85 -> Result<(vec::Vec<u8>, vec::Vec<handle::UntypedHandle>), MojoR
esult> { | |
| 86 let mut num_bytes: u32 = 0; | |
| 87 let mut num_handles: u32 = 0; | |
| 88 let result_prelim = MojoResult::from_code(unsafe { | |
| 89 ffi::MojoReadMessage(self.handle.get_native_handle(), | |
| 90 ptr::null_mut(), | |
| 91 &mut num_bytes as *mut u32, | |
| 92 ptr::null_mut(), | |
| 93 &mut num_handles as *mut u32, | |
| 94 flags) | |
| 95 }); | |
| 96 if result_prelim != MojoResult::ResourceExhausted { | |
| 97 return Err(result_prelim); | |
| 98 } | |
| 99 let mut buf: vec::Vec<u8> = vec::Vec::with_capacity(num_bytes as usize); | |
| 100 let mut raw_handles: vec::Vec<MojoHandle> = vec::Vec::with_capacity(num_
handles as usize); | |
| 101 let buf_ptr; | |
| 102 if num_bytes == 0 { | |
| 103 buf_ptr = ptr::null_mut(); | |
| 104 } else { | |
| 105 buf_ptr = buf.as_mut_ptr() as *mut ffi::c_void; | |
| 106 } | |
| 107 let raw_handles_ptr; | |
| 108 if num_handles == 0 { | |
| 109 raw_handles_ptr = ptr::null_mut(); | |
| 110 } else { | |
| 111 raw_handles_ptr = raw_handles.as_mut_ptr(); | |
| 112 } | |
| 113 let r = MojoResult::from_code(unsafe { | |
| 114 ffi::MojoReadMessage(self.handle.get_native_handle(), | |
| 115 buf_ptr, | |
| 116 &mut num_bytes as *mut u32, | |
| 117 raw_handles_ptr, | |
| 118 &mut num_handles as *mut u32, | |
| 119 flags) | |
| 120 }); | |
| 121 unsafe { | |
| 122 buf.set_len(num_bytes as usize); | |
| 123 raw_handles.set_len(num_handles as usize); | |
| 124 } | |
| 125 let mut handles: vec::Vec<handle::UntypedHandle> = | |
| 126 vec::Vec::with_capacity(num_handles as usize); | |
| 127 for raw_handle in raw_handles.iter() { | |
| 128 handles.push(unsafe { handle::acquire(*raw_handle) }); | |
| 129 } | |
| 130 if r != MojoResult::Okay { | |
| 131 Err(r) | |
| 132 } else { | |
| 133 Ok((buf, handles)) | |
| 134 } | |
| 135 } | |
| 136 | |
| 137 /// Write a message to the endpoint. Messages in Mojo | |
| 138 /// are some set of bytes plus a bunch of handles, so we | |
| 139 /// return both a vector of bytes and a vector of untyped handles. | |
| 140 /// | |
| 141 /// Because the handles are untyped, it is up to the user of this | |
| 142 /// library to know what type the handle actually is and to use | |
| 143 /// from_untyped in order to convert the handle to the correct type. | |
| 144 /// This is abstracted away, however, when using the Mojo bindings | |
| 145 /// generator where you may specify your interface in Mojom. | |
| 146 /// | |
| 147 /// Additionally, the handles passed in are consumed. This is because | |
| 148 /// Mojo handles operate on move semantics much like Rust data types. | |
| 149 /// When a handle is sent through a message pipe it is invalidated and | |
| 150 /// may not even be represented by the same integer on the other side, | |
| 151 /// so care must be taken to design your application with this in mind. | |
| 152 pub fn write(&self, | |
| 153 bytes: &[u8], | |
| 154 mut handles: vec::Vec<handle::UntypedHandle>, | |
| 155 flags: WriteFlags) | |
| 156 -> MojoResult { | |
| 157 let bytes_ptr; | |
| 158 if bytes.len() == 0 { | |
| 159 bytes_ptr = ptr::null(); | |
| 160 } else { | |
| 161 bytes_ptr = bytes.as_ptr() as *const ffi::c_void; | |
| 162 } | |
| 163 let mut raw_handles: vec::Vec<MojoHandle> = vec::Vec::with_capacity(hand
les.len()); | |
| 164 for handle in handles.iter_mut() { | |
| 165 unsafe { | |
| 166 raw_handles.push(handle.get_native_handle()); | |
| 167 handle.invalidate(); | |
| 168 } | |
| 169 } | |
| 170 let raw_handles_ptr; | |
| 171 if raw_handles.len() == 0 { | |
| 172 raw_handles_ptr = ptr::null(); | |
| 173 } else { | |
| 174 raw_handles_ptr = raw_handles.as_ptr(); | |
| 175 } | |
| 176 return MojoResult::from_code(unsafe { | |
| 177 ffi::MojoWriteMessage(self.handle.get_native_handle(), | |
| 178 bytes_ptr, | |
| 179 bytes.len() as u32, | |
| 180 raw_handles_ptr, | |
| 181 raw_handles.len() as u32, | |
| 182 flags) | |
| 183 }); | |
| 184 } | |
| 185 } | |
| 186 | |
| 187 impl CastHandle for MessageEndpoint { | |
| 188 /// Generates a MessageEndpoint from an untyped handle wrapper | |
| 189 /// See mojo::system::handle for information on untyped vs. typed | |
| 190 unsafe fn from_untyped(handle: handle::UntypedHandle) -> Self { | |
| 191 MessageEndpoint { handle: handle } | |
| 192 } | |
| 193 | |
| 194 /// Consumes this object and produces a plain handle wrapper | |
| 195 /// See mojo::system::handle for information on untyped vs. typed | |
| 196 fn as_untyped(self) -> handle::UntypedHandle { | |
| 197 self.handle | |
| 198 } | |
| 199 } | |
| 200 | |
| 201 impl Handle for MessageEndpoint { | |
| 202 /// Returns the native handle wrapped by this structure. | |
| 203 /// | |
| 204 /// See mojo::system::handle for information on handle wrappers | |
| 205 fn get_native_handle(&self) -> MojoHandle { | |
| 206 self.handle.get_native_handle() | |
| 207 } | |
| 208 } | |
| OLD | NEW |