Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(498)

Side by Side Diff: mojo/public/rust/src/bindings/mojom.rs

Issue 2240003002: Rust: Polish off communication across Mojom interfaces (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Upload newest version of code gen Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/public/rust/src/bindings/message.rs ('k') | mojo/public/rust/tests/encoding.rs » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 use bindings::decoding::{Decoder, ValidationError}; 5 use bindings::decoding::{Decoder, ValidationError};
6 use bindings::encoding; 6 use bindings::encoding;
7 use bindings::encoding::{Bits, Encoder, Context, DATA_HEADER_SIZE, DataHeader, D ataHeaderValue}; 7 use bindings::encoding::{Bits, Encoder, Context, DATA_HEADER_SIZE, DataHeader, D ataHeaderValue};
8 use bindings::message::MessageHeader; 8 use bindings::message::MessageHeader;
9 9
10 use std::cmp::Eq; 10 use std::cmp::Eq;
11 use std::collections::HashMap; 11 use std::collections::HashMap;
12 use std::hash::Hash; 12 use std::hash::Hash;
13 use std::mem; 13 use std::mem;
14 use std::panic; 14 use std::panic;
15 use std::ptr; 15 use std::ptr;
16 use std::vec::Vec; 16 use std::vec::Vec;
17 17
18 use system::{CastHandle, Handle, UntypedHandle}; 18 use system::{MojoResult, CastHandle, Handle, UntypedHandle};
19 use system::data_pipe; 19 use system::data_pipe;
20 use system::message_pipe; 20 use system::message_pipe;
21 use system::shared_buffer; 21 use system::shared_buffer;
22 use system::wait_set; 22 use system::wait_set;
23 23
24 /// The size of a Mojom map plus header in bytes. 24 /// The size of a Mojom map plus header in bytes.
25 const MAP_SIZE: usize = 24; 25 const MAP_SIZE: usize = 24;
26 26
27 /// The sorted set of versions for a map. 27 /// The sorted set of versions for a map.
28 const MAP_VERSIONS: [(u32, u32); 1] = [(0, MAP_SIZE as u32)]; 28 const MAP_VERSIONS: [(u32, u32); 1] = [(0, MAP_SIZE as u32)];
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 /// interface, that is, a message pipe which conforms to some 197 /// interface, that is, a message pipe which conforms to some
198 /// messaging interface. 198 /// messaging interface.
199 /// 199 ///
200 /// We force an underlying message pipe to be used via the pipe() 200 /// We force an underlying message pipe to be used via the pipe()
201 /// and unwrap() routines. 201 /// and unwrap() routines.
202 pub trait MojomInterface: MojomEncodable { 202 pub trait MojomInterface: MojomEncodable {
203 /// Get the service name for this interface. 203 /// Get the service name for this interface.
204 fn service_name() -> &'static str; 204 fn service_name() -> &'static str;
205 205
206 /// Get the version for this interface. 206 /// Get the version for this interface.
207 fn version() -> u32; 207 fn version(&self) -> u32;
208 208
209 /// Access the underlying message pipe for this interface. 209 /// Access the underlying message pipe for this interface.
210 fn pipe(&self) -> &message_pipe::MessageEndpoint; 210 fn pipe(&self) -> &message_pipe::MessageEndpoint;
211 211
212 /// Unwrap the interface into its underlying message pipe. 212 /// Unwrap the interface into its underlying message pipe.
213 fn unwrap(self) -> message_pipe::MessageEndpoint; 213 fn unwrap(self) -> message_pipe::MessageEndpoint;
214 } 214 }
215 215
216 /// An error that may occur when sending data over a Mojom interface.
217 #[derive(Debug)]
218 pub enum MojomSendError {
219 /// Failed to write to the underlying message pipe.
220 FailedWrite(MojoResult),
221
222 /// The version is too old to write the attempted message.
223 OldVersion(u32, u32),
224 }
225
216 /// Whatever implements this trait is considered to be a Mojom 226 /// Whatever implements this trait is considered to be a Mojom
217 /// interface that may send messages of some generic type. 227 /// interface that may send messages of some generic type.
218 /// 228 ///
219 /// When implementing this trait, the correct way is to specify 229 /// When implementing this trait, the correct way is to specify
220 /// a tighter trait bound than MojomMessage that limits the types 230 /// a tighter trait bound than MojomMessage that limits the types
221 /// available for sending to those that are valid messages available 231 /// available for sending to those that are valid messages available
222 /// to the interface. 232 /// to the interface.
233 ///
234 /// TODO(mknyszek): Add sending control messages
223 pub trait MojomInterfaceSend<R: MojomMessage>: MojomInterface { 235 pub trait MojomInterfaceSend<R: MojomMessage>: MojomInterface {
224 /// Creates a message. 236 /// Creates a message.
225 fn create_request(&self, payload: R) -> (Vec<u8>, Vec<UntypedHandle>) { 237 fn create_request(&self, req_id: u64, payload: R) -> (Vec<u8>, Vec<UntypedHa ndle>) {
226 let header = R::create_header(); 238 let mut header = R::create_header();
227 // TODO(mknyszek): Calculate and set an actual request id 239 header.request_id = req_id;
228 let header_size = header.compute_size(Default::default()); 240 let header_size = header.compute_size(Default::default());
229 let size = header_size + payload.compute_size(Default::default()); 241 let size = header_size + payload.compute_size(Default::default());
230 let mut buffer: Vec<u8> = Vec::with_capacity(size); 242 let mut buffer: Vec<u8> = Vec::with_capacity(size);
231 buffer.resize(size, 0); 243 buffer.resize(size, 0);
232 let handles = { 244 let handles = {
233 let (header_buf, rest_buf) = buffer.split_at_mut(header_size); 245 let (header_buf, rest_buf) = buffer.split_at_mut(header_size);
234 let mut handles = header.serialize(header_buf); 246 let mut handles = header.serialize(header_buf);
235 handles.extend(payload.serialize(rest_buf).into_iter()); 247 handles.extend(payload.serialize(rest_buf).into_iter());
236 handles 248 handles
237 }; 249 };
238 (buffer, handles) 250 (buffer, handles)
239 } 251 }
240 252
241 /// Creates and sends a message. 253 /// Creates and sends a message, and returns its request ID.
242 fn send_request(&self, payload: R) { 254 fn send_request(&self, req_id: u64, payload: R) -> Result<(), MojomSendError > {
243 let (buffer, handles) = self.create_request(payload); 255 if self.version() < R::min_version() {
244 self.pipe().write(&buffer, handles, mpflags!(Write::None)); 256 return Err(MojomSendError::OldVersion(self.version(), R::min_version ()));
257 }
258 let (buffer, handles) = self.create_request(req_id, payload);
259 match self.pipe().write(&buffer, handles, mpflags!(Write::None)) {
260 MojoResult::Okay => Ok(()),
261 err => Err(MojomSendError::FailedWrite(err)),
262 }
245 } 263 }
246 } 264 }
247 265
266 /// An error that may occur when attempting to recieve a message over a
267 /// Mojom interface.
268 #[derive(Debug)]
269 pub enum MojomRecvError {
270 /// Failed to read from the underlying message pipe.
271 FailedRead(MojoResult),
272
273 /// Failed to validate the buffer during decode.
274 FailedValidation(ValidationError),
275 }
276
248 /// Whatever implements this trait is considered to be a Mojom 277 /// Whatever implements this trait is considered to be a Mojom
249 /// interface that may recieve messages for some interface. 278 /// interface that may recieve messages for some interface.
250 /// 279 ///
251 /// When implementing this trait, specify the container "union" type 280 /// When implementing this trait, specify the container "union" type
252 /// which can contain any of the potential messages that may be recieved. 281 /// which can contain any of the potential messages that may be recieved.
253 /// This way, we can return that type and let the user multiplex over 282 /// This way, we can return that type and let the user multiplex over
254 /// what message was received. 283 /// what message was received.
284 ///
285 /// TODO(mknyszek): Add responding to control messages
255 pub trait MojomInterfaceRecv: MojomInterface { 286 pub trait MojomInterfaceRecv: MojomInterface {
256 type Container: MojomMessageOption; 287 type Container: MojomMessageOption;
257 288
258 /// Tries to read a message from a pipe and decodes it. 289 /// Tries to read a message from a pipe and decodes it.
259 fn recv_response(&self) -> Result<Self::Container, ValidationError> { 290 fn recv_response(&self) -> Result<(u64, Self::Container), MojomRecvError> {
260 // TODO(mknyszek): Actually handle errors with reading 291 match self.pipe().read(mpflags!(Read::None)) {
261 let (buffer, handles) = self.pipe().read(mpflags!(Read::None)).unwrap(); 292 Ok((buffer, handles)) => {
262 Self::Container::decode_message(buffer, handles) 293 match Self::Container::decode_message(buffer, handles) {
294 Ok((req_id, val)) => Ok((req_id, val)),
295 Err(err) => Err(MojomRecvError::FailedValidation(err)),
296 }
297 },
298 Err(err) => Err(MojomRecvError::FailedRead(err)),
299 }
263 } 300 }
264 } 301 }
265 302
266 /// Whatever implements this trait is considered to be a Mojom struct. 303 /// Whatever implements this trait is considered to be a Mojom struct.
267 /// 304 ///
268 /// Mojom structs are always the root of any Mojom message. Thus, we 305 /// Mojom structs are always the root of any Mojom message. Thus, we
269 /// provide convenience functions for serialization here. 306 /// provide convenience functions for serialization here.
270 pub trait MojomStruct: MojomPointer { 307 pub trait MojomStruct: MojomPointer {
271 /// Given a pre-allocated buffer, the struct serializes itself. 308 /// Given a pre-allocated buffer, the struct serializes itself.
272 fn serialize(self, buffer: &mut [u8]) -> Vec<UntypedHandle> { 309 fn serialize(self, buffer: &mut [u8]) -> Vec<UntypedHandle> {
(...skipping 15 matching lines...) Expand all
288 /// Decode the type from a byte array and a set of handles. 325 /// Decode the type from a byte array and a set of handles.
289 fn deserialize(buffer: &[u8], handles: Vec<UntypedHandle>) -> Result<Self, V alidationError> { 326 fn deserialize(buffer: &[u8], handles: Vec<UntypedHandle>) -> Result<Self, V alidationError> {
290 let mut decoder = Decoder::new(buffer, handles); 327 let mut decoder = Decoder::new(buffer, handles);
291 Self::decode_new(&mut decoder, Default::default(), 0) 328 Self::decode_new(&mut decoder, Default::default(), 0)
292 } 329 }
293 } 330 }
294 331
295 /// Marks a MojomStruct as being capable of being sent across some 332 /// Marks a MojomStruct as being capable of being sent across some
296 /// Mojom interface. 333 /// Mojom interface.
297 pub trait MojomMessage: MojomStruct { 334 pub trait MojomMessage: MojomStruct {
335 fn min_version() -> u32;
298 fn create_header() -> MessageHeader; 336 fn create_header() -> MessageHeader;
299 } 337 }
300 338
301 /// The trait for a "container" type intended to be used in MojomInterfaceRecv. 339 /// The trait for a "container" type intended to be used in MojomInterfaceRecv.
302 /// 340 ///
303 /// This trait contains the decode logic which decodes based on the message head er 341 /// This trait contains the decode logic which decodes based on the message head er
304 /// and returns itself: a union type which may contain any of the possible messa ges 342 /// and returns itself: a union type which may contain any of the possible messa ges
305 /// that may be sent across this interface. 343 /// that may be sent across this interface.
306 pub trait MojomMessageOption: Sized { 344 pub trait MojomMessageOption: Sized {
307 /// Decodes the actual payload of the message. 345 /// Decodes the actual payload of the message.
308 /// 346 ///
309 /// Implemented by a code generator. 347 /// Implemented by a code generator.
310 fn decode_payload(header: MessageHeader, buffer: &[u8], handles: Vec<Untyped Handle>) -> Result<Self, ValidationError>; 348 fn decode_payload(header: MessageHeader, buffer: &[u8], handles: Vec<Untyped Handle>) -> Result<Self, ValidationError>;
311 349
312 /// Decodes the message header and then the payload, returning a new 350 /// Decodes the message header and then the payload, returning a new
313 /// copy of itself. 351 /// copy of itself and the request ID found in the header.
314 fn decode_message(buffer: Vec<u8>, handles: Vec<UntypedHandle>) -> Result<Se lf, ValidationError> { 352 fn decode_message(buffer: Vec<u8>, handles: Vec<UntypedHandle>) -> Result<(u 64, Self), ValidationError> {
315 let header = match MessageHeader::deserialize(&buffer[..], Vec::new()) { 353 let header = try!(MessageHeader::deserialize(&buffer[..], Vec::new()));
316 Ok(header) => header,
317 Err(err) => return Err(err),
318 };
319 let payload_buffer = &buffer[header.serialized_size(&Default::default()) ..]; 354 let payload_buffer = &buffer[header.serialized_size(&Default::default()) ..];
320 Self::decode_payload(header, payload_buffer, handles) 355 let req_id = header.request_id;
356 let ret = try!(Self::decode_payload(header, payload_buffer, handles));
357 Ok((req_id, ret))
321 } 358 }
322 } 359 }
323 360
324 // ********************************************** // 361 // ********************************************** //
325 // ****** IMPLEMENTATIONS FOR COMMON TYPES ****** // 362 // ****** IMPLEMENTATIONS FOR COMMON TYPES ****** //
326 // ********************************************** // 363 // ********************************************** //
327 364
328 macro_rules! impl_encodable_for_prim { 365 macro_rules! impl_encodable_for_prim {
329 ($($prim_type:ty),*) => { 366 ($($prim_type:ty),*) => {
330 $( 367 $(
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 impl_encodable_for_handle!(data_pipe::Consumer<T>); 888 impl_encodable_for_handle!(data_pipe::Consumer<T>);
852 } 889 }
853 890
854 impl<T> MojomEncodable for data_pipe::Producer<T> { 891 impl<T> MojomEncodable for data_pipe::Producer<T> {
855 impl_encodable_for_handle!(data_pipe::Producer<T>); 892 impl_encodable_for_handle!(data_pipe::Producer<T>);
856 } 893 }
857 894
858 impl MojomEncodable for wait_set::WaitSet { 895 impl MojomEncodable for wait_set::WaitSet {
859 impl_encodable_for_handle!(wait_set::WaitSet); 896 impl_encodable_for_handle!(wait_set::WaitSet);
860 } 897 }
OLDNEW
« no previous file with comments | « mojo/public/rust/src/bindings/message.rs ('k') | mojo/public/rust/tests/encoding.rs » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698