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