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 <stdint.h> | 8 #include <stdint.h> |
9 #include <limits> | 9 #include <limits> |
10 | 10 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 }; | 186 }; |
187 | 187 |
188 // Should have zero overhead. | 188 // Should have zero overhead. |
189 static_assert(sizeof(Handle) == sizeof(MojoHandle), "Bad size for C++ Handle"); | 189 static_assert(sizeof(Handle) == sizeof(MojoHandle), "Bad size for C++ Handle"); |
190 | 190 |
191 // The scoper should also impose no more overhead. | 191 // The scoper should also impose no more overhead. |
192 typedef ScopedHandleBase<Handle> ScopedHandle; | 192 typedef ScopedHandleBase<Handle> ScopedHandle; |
193 static_assert(sizeof(ScopedHandle) == sizeof(Handle), | 193 static_assert(sizeof(ScopedHandle) == sizeof(Handle), |
194 "Bad size for C++ ScopedHandle"); | 194 "Bad size for C++ ScopedHandle"); |
195 | 195 |
196 inline MojoResult Wait(Handle handle, | |
197 MojoHandleSignals signals, | |
198 MojoDeadline deadline, | |
199 MojoHandleSignalsState* signals_state) { | |
200 return MojoWait(handle.value(), signals, deadline, signals_state); | |
201 } | |
202 | |
203 const uint32_t kInvalidWaitManyIndexValue = static_cast<uint32_t>(-1); | |
204 | |
205 // Simplify the interpretation of the output from |MojoWaitMany()|. | |
206 class WaitManyResult { | |
207 public: | |
208 explicit WaitManyResult(MojoResult mojo_wait_many_result) | |
209 : result(mojo_wait_many_result), index(kInvalidWaitManyIndexValue) {} | |
210 | |
211 WaitManyResult(MojoResult mojo_wait_many_result, uint32_t result_index) | |
212 : result(mojo_wait_many_result), index(result_index) {} | |
213 | |
214 // A valid handle index is always returned if |WaitMany()| succeeds, but may | |
215 // or may not be returned if |WaitMany()| returns an error. Use this helper | |
216 // function to check if |index| is a valid index into the handle array. | |
217 bool IsIndexValid() const { return index != kInvalidWaitManyIndexValue; } | |
218 | |
219 // The |signals_states| array is always returned by |WaitMany()| on success, | |
220 // but may or may not be returned if |WaitMany()| returns an error. Use this | |
221 // helper function to check if |signals_states| holds valid data. | |
222 bool AreSignalsStatesValid() const { | |
223 return result != MOJO_RESULT_INVALID_ARGUMENT && | |
224 result != MOJO_RESULT_RESOURCE_EXHAUSTED; | |
225 } | |
226 | |
227 MojoResult result; | |
228 uint32_t index; | |
229 }; | |
230 | |
231 // |HandleVectorType| and |FlagsVectorType| should be similar enough to | |
232 // |std::vector<Handle>| and |std::vector<MojoHandleSignals>|, respectively: | |
233 // - They should have a (const) |size()| method that returns an unsigned type. | |
234 // - They must provide contiguous storage, with access via (const) reference to | |
235 // that storage provided by a (const) |operator[]()| (by reference). | |
236 template <class HandleVectorType, | |
237 class FlagsVectorType, | |
238 class SignalsStateVectorType> | |
239 inline WaitManyResult WaitMany(const HandleVectorType& handles, | |
240 const FlagsVectorType& signals, | |
241 MojoDeadline deadline, | |
242 SignalsStateVectorType* signals_states) { | |
243 if (signals.size() != handles.size() || | |
244 (signals_states && signals_states->size() != signals.size())) | |
245 return WaitManyResult(MOJO_RESULT_INVALID_ARGUMENT); | |
246 if (handles.size() >= kInvalidWaitManyIndexValue) | |
247 return WaitManyResult(MOJO_RESULT_RESOURCE_EXHAUSTED); | |
248 | |
249 if (handles.size() == 0) { | |
250 return WaitManyResult( | |
251 MojoWaitMany(nullptr, nullptr, 0, deadline, nullptr, nullptr)); | |
252 } | |
253 | |
254 uint32_t result_index = kInvalidWaitManyIndexValue; | |
255 const Handle& first_handle = handles[0]; | |
256 const MojoHandleSignals& first_signals = signals[0]; | |
257 MojoHandleSignalsState* first_state = | |
258 signals_states ? &(*signals_states)[0] : nullptr; | |
259 MojoResult result = | |
260 MojoWaitMany(reinterpret_cast<const MojoHandle*>(&first_handle), | |
261 &first_signals, static_cast<uint32_t>(handles.size()), | |
262 deadline, &result_index, first_state); | |
263 return WaitManyResult(result, result_index); | |
264 } | |
265 | |
266 // C++ 4.10, regarding pointer conversion, says that an integral null pointer | |
267 // constant can be converted to |std::nullptr_t| (which is a typedef for | |
268 // |decltype(nullptr)|). The opposite direction is not allowed. | |
269 template <class HandleVectorType, class FlagsVectorType> | |
270 inline WaitManyResult WaitMany(const HandleVectorType& handles, | |
271 const FlagsVectorType& signals, | |
272 MojoDeadline deadline, | |
273 decltype(nullptr) signals_states) { | |
274 if (signals.size() != handles.size()) | |
275 return WaitManyResult(MOJO_RESULT_INVALID_ARGUMENT); | |
276 if (handles.size() >= kInvalidWaitManyIndexValue) | |
277 return WaitManyResult(MOJO_RESULT_RESOURCE_EXHAUSTED); | |
278 | |
279 if (handles.size() == 0) { | |
280 return WaitManyResult( | |
281 MojoWaitMany(nullptr, nullptr, 0, deadline, nullptr, nullptr)); | |
282 } | |
283 | |
284 uint32_t result_index = kInvalidWaitManyIndexValue; | |
285 const Handle& first_handle = handles[0]; | |
286 const MojoHandleSignals& first_signals = signals[0]; | |
287 MojoResult result = MojoWaitMany( | |
288 reinterpret_cast<const MojoHandle*>(&first_handle), &first_signals, | |
289 static_cast<uint32_t>(handles.size()), deadline, &result_index, nullptr); | |
290 return WaitManyResult(result, result_index); | |
291 } | |
292 | |
293 // |Close()| takes ownership of the handle, since it'll invalidate it. | 196 // |Close()| takes ownership of the handle, since it'll invalidate it. |
294 // Note: There's nothing to do, since the argument will be destroyed when it | 197 // Note: There's nothing to do, since the argument will be destroyed when it |
295 // goes out of scope. | 198 // goes out of scope. |
296 template <class HandleType> | 199 template <class HandleType> |
297 inline void Close(ScopedHandleBase<HandleType> /*handle*/) { | 200 inline void Close(ScopedHandleBase<HandleType> /*handle*/) { |
298 } | 201 } |
299 | 202 |
300 // Most users should typically use |Close()| (above) instead. | 203 // Most users should typically use |Close()| (above) instead. |
301 inline MojoResult CloseRaw(Handle handle) { | 204 inline MojoResult CloseRaw(Handle handle) { |
302 return MojoClose(handle.value()); | 205 return MojoClose(handle.value()); |
303 } | 206 } |
304 | 207 |
305 // Strict weak ordering, so that |Handle|s can be used as keys in |std::map|s, | 208 // Strict weak ordering, so that |Handle|s can be used as keys in |std::map|s, |
306 inline bool operator<(const Handle a, const Handle b) { | 209 inline bool operator<(const Handle a, const Handle b) { |
307 return a.value() < b.value(); | 210 return a.value() < b.value(); |
308 } | 211 } |
309 | 212 |
310 // Comparison, so that |Handle|s can be used as keys in hash maps. | 213 // Comparison, so that |Handle|s can be used as keys in hash maps. |
311 inline bool operator==(const Handle a, const Handle b) { | 214 inline bool operator==(const Handle a, const Handle b) { |
312 return a.value() == b.value(); | 215 return a.value() == b.value(); |
313 } | 216 } |
314 | 217 |
315 } // namespace mojo | 218 } // namespace mojo |
316 | 219 |
317 #endif // MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_ | 220 #endif // MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_ |
OLD | NEW |