handle.h revision 116680a4aac90f2aa7413d9095a592090648e557
1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file. 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#ifndef MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_ 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_ 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <assert.h> 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <limits> 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/c/system/functions.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/c/system/types.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/system/macros.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace mojo { 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// OVERVIEW 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |Handle| and |...Handle|: 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |Handle| is a simple, copyable wrapper for the C type |MojoHandle| (which is 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// just an integer). Its purpose is to increase type-safety, not provide 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// lifetime management. For the same purpose, we have trivial *subclasses* of 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |Handle|, e.g., |MessagePipeHandle| and |DataPipeProducerHandle|. |Handle| 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// and its subclasses impose *no* extra overhead over using |MojoHandle|s 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// directly. 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Note that though we provide constructors for |Handle|/|...Handle| from a 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |MojoHandle|, we do not provide, e.g., a constructor for |MessagePipeHandle| 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// from a |Handle|. This is for type safety: If we did, you'd then be able to 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// construct a |MessagePipeHandle| from, e.g., a |DataPipeProducerHandle| (since 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// it's a |Handle|). 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |ScopedHandleBase| and |Scoped...Handle|: 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |ScopedHandleBase<HandleType>| is a templated scoped wrapper, for the handle 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// types above (in the same sense that a C++11 |unique_ptr<T>| is a scoped 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// wrapper for a |T*|). It provides lifetime management, closing its owned 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// handle on destruction. It also provides (emulated) move semantics, again 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// along the lines of C++11's |unique_ptr| (and exactly like Chromium's 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |scoped_ptr|). 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |ScopedHandle| is just (a typedef of) a |ScopedHandleBase<Handle>|. 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Similarly, |ScopedMessagePipeHandle| is just a 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |ScopedHandleBase<MessagePipeHandle>|. Etc. Note that a 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |ScopedMessagePipeHandle| is *not* a (subclass of) |ScopedHandle|. 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Wrapper functions: 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// We provide simple wrappers for the |Mojo...()| functions (in 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// mojo/public/c/system/core.h -- see that file for details on individual 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// functions). 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// The general guideline is functions that imply ownership transfer of a handle 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// should take (or produce) an appropriate |Scoped...Handle|, while those that 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// don't take a |...Handle|. For example, |CreateMessagePipe()| has two 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |ScopedMessagePipe| "out" parameters, whereas |Wait()| and |WaitMany()| take 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |Handle| parameters. Some, have both: e.g., |DuplicatedBuffer()| takes a 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// suitable (unscoped) handle (e.g., |SharedBufferHandle|) "in" parameter and 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// produces a suitable scoped handle (e.g., |ScopedSharedBufferHandle| a.k.a. 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |ScopedHandleBase<SharedBufferHandle>|) as an "out" parameter. 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// An exception are some of the |...Raw()| functions. E.g., |CloseRaw()| takes a 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |Handle|, leaving the user to discard the handle. 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// More significantly, |WriteMessageRaw()| exposes the full API complexity of 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |MojoWriteMessage()| (but doesn't require any extra overhead). It takes a raw 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// array of |Handle|s as input, and takes ownership of them (i.e., invalidates 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// them) on *success* (but not on failure). There are a number of reasons for 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// this. First, C++03 |std::vector|s cannot contain the move-only 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |Scoped...Handle|s. Second, |std::vector|s impose extra overhead 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// (necessitating heap-allocation of the buffer). Third, |std::vector|s wouldn't 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// provide the desired level of flexibility/safety: a vector of handles would 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// have to be all of the same type (probably |Handle|/|ScopedHandle|). Fourth, 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// it's expected to not be used directly, but instead be used by generated 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// bindings. 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Other |...Raw()| functions expose similar rough edges, e.g., dealing with raw 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// pointers (and lengths) instead of taking |std::vector|s or similar. 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// ScopedHandleBase ------------------------------------------------------------ 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Scoper for the actual handle types defined further below. It's move-only, 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// like the C++11 |unique_ptr|. 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <class HandleType> 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass ScopedHandleBase { 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(ScopedHandleBase, RValue) 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public: 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScopedHandleBase() {} 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch explicit ScopedHandleBase(HandleType handle) : handle_(handle) {} 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ~ScopedHandleBase() { CloseIfNecessary(); } 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch template <class CompatibleHandleType> 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch explicit ScopedHandleBase(ScopedHandleBase<CompatibleHandleType> other) 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : handle_(other.release()) { 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Move-only constructor and operator=. 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScopedHandleBase(RValue other) : handle_(other.object->release()) {} 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScopedHandleBase& operator=(RValue other) { 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (other.object != this) { 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CloseIfNecessary(); 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch handle_ = other.object->release(); 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return *this; 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const HandleType& get() const { return handle_; } 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch template <typename PassedHandleType> 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static ScopedHandleBase<HandleType> From( 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScopedHandleBase<PassedHandleType> other) { 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MOJO_COMPILE_ASSERT( 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sizeof(static_cast<PassedHandleType*>(static_cast<HandleType*>(0))), 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch HandleType_is_not_a_subtype_of_PassedHandleType); 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ScopedHandleBase<HandleType>( 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static_cast<HandleType>(other.release().value())); 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void swap(ScopedHandleBase& other) { 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch handle_.swap(other.handle_); 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch HandleType release() MOJO_WARN_UNUSED_RESULT { 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch HandleType rv; 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rv.swap(handle_); 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return rv; 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void reset(HandleType handle = HandleType()) { 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CloseIfNecessary(); 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch handle_ = handle; 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool is_valid() const { 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return handle_.is_valid(); 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private: 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void CloseIfNecessary() { 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!handle_.is_valid()) 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MojoResult result MOJO_ALLOW_UNUSED = MojoClose(handle_.value()); 145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch assert(result == MOJO_RESULT_OK); 146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch HandleType handle_; 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 151116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <typename HandleType> 152116680a4aac90f2aa7413d9095a592090648e557Ben Murdochinline ScopedHandleBase<HandleType> MakeScopedHandle(HandleType handle) { 153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ScopedHandleBase<HandleType>(handle); 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Handle ---------------------------------------------------------------------- 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst MojoHandle kInvalidHandleValue = MOJO_HANDLE_INVALID; 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Wrapper base class for |MojoHandle|. 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass Handle { 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public: 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Handle() : value_(kInvalidHandleValue) {} 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch explicit Handle(MojoHandle value) : value_(value) {} 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ~Handle() {} 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void swap(Handle& other) { 168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MojoHandle temp = value_; 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch value_ = other.value_; 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch other.value_ = temp; 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool is_valid() const { 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return value_ != kInvalidHandleValue; 175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MojoHandle value() const { return value_; } 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MojoHandle* mutable_value() { return &value_; } 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void set_value(MojoHandle value) { value_ = value; } 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private: 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MojoHandle value_; 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Copying and assignment allowed. 185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Should have zero overhead. 188116680a4aac90f2aa7413d9095a592090648e557Ben MurdochMOJO_COMPILE_ASSERT(sizeof(Handle) == sizeof(MojoHandle), 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bad_size_for_cpp_Handle); 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// The scoper should also impose no more overhead. 192116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtypedef ScopedHandleBase<Handle> ScopedHandle; 193116680a4aac90f2aa7413d9095a592090648e557Ben MurdochMOJO_COMPILE_ASSERT(sizeof(ScopedHandle) == sizeof(Handle), 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bad_size_for_cpp_ScopedHandle); 195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdochinline MojoResult Wait(const Handle& handle, 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MojoHandleSignals signals, 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MojoDeadline deadline) { 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return MojoWait(handle.value(), signals, deadline); 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |HandleVectorType| and |FlagsVectorType| should be similar enough to 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |std::vector<Handle>| and |std::vector<MojoHandleSignals>|, respectively: 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// - They should have a (const) |size()| method that returns an unsigned type. 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// - They must provide contiguous storage, with access via (const) reference to 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// that storage provided by a (const) |operator[]()| (by reference). 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <class HandleVectorType, class FlagsVectorType> 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdochinline MojoResult WaitMany(const HandleVectorType& handles, 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const FlagsVectorType& signals, 210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MojoDeadline deadline) { 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (signals.size() != handles.size()) 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return MOJO_RESULT_INVALID_ARGUMENT; 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (handles.size() > std::numeric_limits<uint32_t>::max()) 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return MOJO_RESULT_OUT_OF_RANGE; 215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (handles.size() == 0) 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return MojoWaitMany(NULL, NULL, 0, deadline); 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Handle& first_handle = handles[0]; 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const MojoHandleSignals& first_signals = signals[0]; 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return MojoWaitMany( 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch reinterpret_cast<const MojoHandle*>(&first_handle), 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch reinterpret_cast<const MojoHandleSignals*>(&first_signals), 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static_cast<uint32_t>(handles.size()), 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch deadline); 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// |Close()| takes ownership of the handle, since it'll invalidate it. 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Note: There's nothing to do, since the argument will be destroyed when it 230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// goes out of scope. 231116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <class HandleType> 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdochinline void Close(ScopedHandleBase<HandleType> /*handle*/) {} 233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Most users should typically use |Close()| (above) instead. 235116680a4aac90f2aa7413d9095a592090648e557Ben Murdochinline MojoResult CloseRaw(Handle handle) { 236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return MojoClose(handle.value()); 237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Strict weak ordering, so that |Handle|s can be used as keys in |std::map|s, 240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// etc. 241116680a4aac90f2aa7413d9095a592090648e557Ben Murdochinline bool operator<(const Handle& a, const Handle& b) { 242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return a.value() < b.value(); 243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace mojo 246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif // MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_ 248