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::ptr; | |
7 | |
8 use system::ffi; | |
9 use system::handle; | |
10 use system::handle::{CastHandle, Handle}; | |
11 use system::mojo_types; | |
12 use system::mojo_types::MojoResult; | |
13 | |
14 #[repr(u32)] | |
15 /// Create flags for wait sets | |
16 pub enum Create { | |
17 None = 0, | |
18 } | |
19 | |
20 #[repr(u32)] | |
21 /// Add flags for wait sets | |
22 pub enum Add { | |
23 None = 0, | |
24 } | |
25 | |
26 /// This struct represents a handle to a wait set in the Mojo system. | |
27 /// | |
28 /// The primary purpose of a wait set is to provide an abstraction for | |
29 /// efficiently waiting asynchronously (and cooperatively) on a set of | |
30 /// handles which are registered with it. | |
31 pub struct WaitSet { | |
32 handle: handle::UntypedHandle, | |
33 } | |
34 | |
35 impl WaitSet { | |
36 /// Creates a new WaitSet object in the Mojo system, and returns a wrapper | |
37 /// for it. If creation fails, returns the result code. | |
38 pub fn new(flags: mojo_types::CreateFlags) -> Result<WaitSet, MojoResult> { | |
39 let mut raw_handle: mojo_types::MojoHandle = 0; | |
40 let opts = ffi::MojoCreateWaitSetOptions { | |
41 struct_size: mem::size_of::<ffi::MojoCreateWaitSetOptions>() as u32, | |
42 flags: flags, | |
43 _align: [], | |
44 }; | |
45 let raw_opts = &opts as *const ffi::MojoCreateWaitSetOptions; | |
46 let r = MojoResult::from_code(unsafe { | |
47 ffi::MojoCreateWaitSet(raw_opts, &mut raw_handle as *mut mojo_types:
:MojoHandle) | |
48 }); | |
49 if r != MojoResult::Okay { | |
50 Err(r) | |
51 } else { | |
52 Ok(WaitSet { handle: unsafe { handle::acquire(raw_handle) } }) | |
53 } | |
54 } | |
55 | |
56 /// Adds a handle to the underlying wait set. | |
57 /// | |
58 /// The handle that is added may go invalid, at which point the result | |
59 /// returned from wait_on_set for this handle will be `Cancelled'. | |
60 /// | |
61 /// One can pass in a unique cookie value which is used to identify the | |
62 /// handle in the wait result. Currently there are no supported flags, | |
63 /// but the argument is kept for future usage. | |
64 pub fn add(&mut self, | |
65 handle: &Handle, | |
66 signals: mojo_types::HandleSignals, | |
67 cookie: u64, | |
68 flags: mojo_types::AddFlags) | |
69 -> MojoResult { | |
70 let opts = ffi::MojoWaitSetAddOptions { | |
71 struct_size: mem::size_of::<ffi::MojoWaitSetAddOptions>() as u32, | |
72 flags: flags, | |
73 _align: [], | |
74 }; | |
75 let raw_opts = &opts as *const ffi::MojoWaitSetAddOptions; | |
76 MojoResult::from_code(unsafe { | |
77 ffi::MojoWaitSetAdd(self.handle.get_native_handle(), | |
78 handle.get_native_handle(), | |
79 signals, | |
80 cookie, | |
81 raw_opts) | |
82 }) | |
83 } | |
84 | |
85 /// Removes a handle from the underlying wait set by cookie value. | |
86 pub fn remove(&mut self, cookie: u64) -> MojoResult { | |
87 MojoResult::from_code(unsafe { ffi::MojoWaitSetRemove(self.get_native_ha
ndle(), cookie) }) | |
88 } | |
89 | |
90 /// Waits on this wait set. | |
91 /// | |
92 /// The conditions for the wait to end include: | |
93 /// * A handle has its requested signals satisfied. | |
94 /// * A handle is determined to never be able to have its requested | |
95 /// signals satisfied. | |
96 /// * The deadline expires. | |
97 /// * This wait set handle becomes invalid (Fatal error in this bindings). | |
98 /// | |
99 /// On a successful wait, we return the maximum number of results that could | |
100 /// possibly be returned (similar to the total number of registered handles)
. | |
101 /// Additionally, populates the output vector with the results of each handl
e | |
102 /// that completed waiting. | |
103 /// | |
104 /// On a failed wait, we return the result code. | |
105 pub fn wait_on_set(&self, | |
106 deadline: mojo_types::MojoDeadline, | |
107 output: &mut Vec<mojo_types::WaitSetResult>) | |
108 -> Result<u32, MojoResult> { | |
109 assert!((output.capacity() as u64) <= ((1 as u64) << 32)); | |
110 let mut num_results = output.capacity() as u32; | |
111 let mut max_results: u32 = 0; | |
112 let mut output_ptr = output.as_mut_ptr(); | |
113 if num_results == 0 { | |
114 output_ptr = ptr::null_mut(); | |
115 } | |
116 let r = MojoResult::from_code(unsafe { | |
117 ffi::MojoWaitSetWait(self.handle.get_native_handle(), | |
118 deadline, | |
119 &mut num_results as *mut u32, | |
120 output_ptr, | |
121 &mut max_results as *mut u32) | |
122 }); | |
123 unsafe { | |
124 output.set_len(num_results as usize); | |
125 } | |
126 if r == MojoResult::Okay { | |
127 Ok(max_results) | |
128 } else { | |
129 Err(r) | |
130 } | |
131 } | |
132 } | |
133 | |
134 impl CastHandle for WaitSet { | |
135 /// Generates a WaitSet from an untyped handle wrapper | |
136 /// See mojo::system::handle for information on untyped vs. typed | |
137 unsafe fn from_untyped(handle: handle::UntypedHandle) -> Self { | |
138 WaitSet { handle: handle } | |
139 } | |
140 | |
141 /// Consumes this object and produces a plain handle wrapper | |
142 /// See mojo::system::handle for information on untyped vs. typed | |
143 fn as_untyped(self) -> handle::UntypedHandle { | |
144 self.handle | |
145 } | |
146 } | |
147 | |
148 impl Handle for WaitSet { | |
149 /// Returns the native handle wrapped by this structure. | |
150 /// | |
151 /// See mojo::system::handle for information on handle wrappers | |
152 fn get_native_handle(&self) -> mojo_types::MojoHandle { | |
153 self.handle.get_native_handle() | |
154 } | |
155 } | |
OLD | NEW |