OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_ | 5 #ifndef MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_ |
6 #define MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_ | 6 #define MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_ |
7 | 7 |
8 #include <assert.h> | 8 #include <assert.h> |
| 9 #include <stdint.h> |
| 10 |
9 #include <limits> | 11 #include <limits> |
10 | 12 |
11 #include "mojo/public/c/system/handle.h" | 13 #include "mojo/public/c/system/handle.h" |
12 #include "mojo/public/c/system/result.h" | 14 #include "mojo/public/c/system/result.h" |
13 #include "mojo/public/c/system/time.h" | |
14 #include "mojo/public/c/system/wait.h" | |
15 #include "mojo/public/cpp/system/macros.h" | 15 #include "mojo/public/cpp/system/macros.h" |
16 | 16 |
17 namespace mojo { | 17 namespace mojo { |
18 | 18 |
19 // OVERVIEW | 19 // OVERVIEW |
20 // | 20 // |
21 // |Handle| and |...Handle|: | 21 // |Handle| and |...Handle|: |
22 // | 22 // |
23 // |Handle| is a simple, copyable wrapper for the C type |MojoHandle| (which is | 23 // |Handle| is a simple, copyable wrapper for the C type |MojoHandle| (which is |
24 // just an integer). Its purpose is to increase type-safety, not provide | 24 // just an integer). Its purpose is to increase type-safety, not provide |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 }; | 166 }; |
167 | 167 |
168 // Should have zero overhead. | 168 // Should have zero overhead. |
169 static_assert(sizeof(Handle) == sizeof(MojoHandle), "Bad size for C++ Handle"); | 169 static_assert(sizeof(Handle) == sizeof(MojoHandle), "Bad size for C++ Handle"); |
170 | 170 |
171 // The scoper should also impose no more overhead. | 171 // The scoper should also impose no more overhead. |
172 typedef ScopedHandleBase<Handle> ScopedHandle; | 172 typedef ScopedHandleBase<Handle> ScopedHandle; |
173 static_assert(sizeof(ScopedHandle) == sizeof(Handle), | 173 static_assert(sizeof(ScopedHandle) == sizeof(Handle), |
174 "Bad size for C++ ScopedHandle"); | 174 "Bad size for C++ ScopedHandle"); |
175 | 175 |
176 inline MojoResult Wait(Handle handle, | |
177 MojoHandleSignals signals, | |
178 MojoDeadline deadline, | |
179 MojoHandleSignalsState* signals_state) { | |
180 return MojoWait(handle.value(), signals, deadline, signals_state); | |
181 } | |
182 | |
183 const uint32_t kInvalidWaitManyIndexValue = static_cast<uint32_t>(-1); | |
184 | |
185 // Simplify the interpretation of the output from |MojoWaitMany()|. | |
186 class WaitManyResult { | |
187 public: | |
188 explicit WaitManyResult(MojoResult mojo_wait_many_result) | |
189 : result(mojo_wait_many_result), index(kInvalidWaitManyIndexValue) {} | |
190 | |
191 WaitManyResult(MojoResult mojo_wait_many_result, uint32_t result_index) | |
192 : result(mojo_wait_many_result), index(result_index) {} | |
193 | |
194 // A valid handle index is always returned if |WaitMany()| succeeds, but may | |
195 // or may not be returned if |WaitMany()| returns an error. Use this helper | |
196 // function to check if |index| is a valid index into the handle array. | |
197 bool IsIndexValid() const { return index != kInvalidWaitManyIndexValue; } | |
198 | |
199 // The |signals_states| array is always returned by |WaitMany()| on success, | |
200 // but may or may not be returned if |WaitMany()| returns an error. Use this | |
201 // helper function to check if |signals_states| holds valid data. | |
202 bool AreSignalsStatesValid() const { | |
203 return result != MOJO_RESULT_INVALID_ARGUMENT && | |
204 result != MOJO_RESULT_RESOURCE_EXHAUSTED; | |
205 } | |
206 | |
207 MojoResult result; | |
208 uint32_t index; | |
209 }; | |
210 | |
211 // |HandleVectorType| and |FlagsVectorType| should be similar enough to | |
212 // |std::vector<Handle>| and |std::vector<MojoHandleSignals>|, respectively: | |
213 // - They should have a (const) |size()| method that returns an unsigned type. | |
214 // - They must provide contiguous storage, with access via (const) reference to | |
215 // that storage provided by a (const) |operator[]()| (by reference). | |
216 template <class HandleVectorType, | |
217 class FlagsVectorType, | |
218 class SignalsStateVectorType> | |
219 inline WaitManyResult WaitMany(const HandleVectorType& handles, | |
220 const FlagsVectorType& signals, | |
221 MojoDeadline deadline, | |
222 SignalsStateVectorType* signals_states) { | |
223 if (signals.size() != handles.size() || | |
224 (signals_states && signals_states->size() != signals.size())) | |
225 return WaitManyResult(MOJO_RESULT_INVALID_ARGUMENT); | |
226 if (handles.size() >= kInvalidWaitManyIndexValue) | |
227 return WaitManyResult(MOJO_RESULT_RESOURCE_EXHAUSTED); | |
228 | |
229 if (handles.size() == 0) { | |
230 return WaitManyResult( | |
231 MojoWaitMany(nullptr, nullptr, 0, deadline, nullptr, nullptr)); | |
232 } | |
233 | |
234 uint32_t result_index = kInvalidWaitManyIndexValue; | |
235 const Handle& first_handle = handles[0]; | |
236 const MojoHandleSignals& first_signals = signals[0]; | |
237 MojoHandleSignalsState* first_state = | |
238 signals_states ? &(*signals_states)[0] : nullptr; | |
239 MojoResult result = | |
240 MojoWaitMany(reinterpret_cast<const MojoHandle*>(&first_handle), | |
241 &first_signals, static_cast<uint32_t>(handles.size()), | |
242 deadline, &result_index, first_state); | |
243 return WaitManyResult(result, result_index); | |
244 } | |
245 | |
246 // C++ 4.10, regarding pointer conversion, says that an integral null pointer | |
247 // constant can be converted to |std::nullptr_t| (which is a typedef for | |
248 // |decltype(nullptr)|). The opposite direction is not allowed. | |
249 template <class HandleVectorType, class FlagsVectorType> | |
250 inline WaitManyResult WaitMany(const HandleVectorType& handles, | |
251 const FlagsVectorType& signals, | |
252 MojoDeadline deadline, | |
253 decltype(nullptr) signals_states) { | |
254 if (signals.size() != handles.size()) | |
255 return WaitManyResult(MOJO_RESULT_INVALID_ARGUMENT); | |
256 if (handles.size() >= kInvalidWaitManyIndexValue) | |
257 return WaitManyResult(MOJO_RESULT_RESOURCE_EXHAUSTED); | |
258 | |
259 if (handles.size() == 0) { | |
260 return WaitManyResult( | |
261 MojoWaitMany(nullptr, nullptr, 0, deadline, nullptr, nullptr)); | |
262 } | |
263 | |
264 uint32_t result_index = kInvalidWaitManyIndexValue; | |
265 const Handle& first_handle = handles[0]; | |
266 const MojoHandleSignals& first_signals = signals[0]; | |
267 MojoResult result = MojoWaitMany( | |
268 reinterpret_cast<const MojoHandle*>(&first_handle), &first_signals, | |
269 static_cast<uint32_t>(handles.size()), deadline, &result_index, nullptr); | |
270 return WaitManyResult(result, result_index); | |
271 } | |
272 | |
273 // |Close()| takes ownership of the handle, since it'll invalidate it. | 176 // |Close()| takes ownership of the handle, since it'll invalidate it. |
274 // Note: There's nothing to do, since the argument will be destroyed when it | 177 // Note: There's nothing to do, since the argument will be destroyed when it |
275 // goes out of scope. | 178 // goes out of scope. |
276 template <class HandleType> | 179 template <class HandleType> |
277 inline void Close(ScopedHandleBase<HandleType> /*handle*/) { | 180 inline void Close(ScopedHandleBase<HandleType> /*handle*/) { |
278 } | 181 } |
279 | 182 |
280 // Most users should typically use |Close()| (above) instead. | 183 // Most users should typically use |Close()| (above) instead. |
281 inline MojoResult CloseRaw(Handle handle) { | 184 inline MojoResult CloseRaw(Handle handle) { |
282 return MojoClose(handle.value()); | 185 return MojoClose(handle.value()); |
283 } | 186 } |
284 | 187 |
285 // Strict weak ordering, so that |Handle|s can be used as keys in |std::map|s, | 188 // Strict weak ordering, so that |Handle|s can be used as keys in |std::map|s, |
286 inline bool operator<(const Handle a, const Handle b) { | 189 inline bool operator<(const Handle a, const Handle b) { |
287 return a.value() < b.value(); | 190 return a.value() < b.value(); |
288 } | 191 } |
289 | 192 |
290 } // namespace mojo | 193 } // namespace mojo |
291 | 194 |
292 #endif // MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_ | 195 #endif // MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_ |
OLD | NEW |