| 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 |