Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(464)

Side by Side Diff: mojo/public/cpp/system/handle.h

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/public/cpp/system/data_pipe.h ('k') | mojo/public/cpp/system/macros.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #ifndef MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_
6 #define MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_
7
8 #include <assert.h>
9 #include <mojo/result.h>
10 #include <mojo/system/handle.h>
11 #include <stdint.h>
12
13 #include <limits>
14
15 #include "mojo/public/cpp/system/macros.h"
16
17 namespace mojo {
18
19 // OVERVIEW
20 //
21 // |Handle| and |...Handle|:
22 //
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
25 // lifetime management. For the same purpose, we have trivial *subclasses* of
26 // |Handle|, e.g., |MessagePipeHandle| and |DataPipeProducerHandle|. |Handle|
27 // and its subclasses impose *no* extra overhead over using |MojoHandle|s
28 // directly.
29 //
30 // Note that though we provide constructors for |Handle|/|...Handle| from a
31 // |MojoHandle|, we do not provide, e.g., a constructor for |MessagePipeHandle|
32 // from a |Handle|. This is for type safety: If we did, you'd then be able to
33 // construct a |MessagePipeHandle| from, e.g., a |DataPipeProducerHandle| (since
34 // it's a |Handle|).
35 //
36 // |ScopedHandleBase| and |Scoped...Handle|:
37 //
38 // |ScopedHandleBase<HandleType>| is a templated scoped wrapper, for the handle
39 // types above (in the same sense that a C++11 |unique_ptr<T>| is a scoped
40 // wrapper for a |T*|). It provides lifetime management, closing its owned
41 // handle on destruction. It also provides (emulated) move semantics, again
42 // along the lines of C++11's |unique_ptr| (and exactly like Chromium's
43 // |scoped_ptr|).
44 //
45 // |ScopedHandle| is just (a typedef of) a |ScopedHandleBase<Handle>|.
46 // Similarly, |ScopedMessagePipeHandle| is just a
47 // |ScopedHandleBase<MessagePipeHandle>|. Etc. Note that a
48 // |ScopedMessagePipeHandle| is *not* a (subclass of) |ScopedHandle|.
49 //
50 // Wrapper functions:
51 //
52 // We provide simple wrappers for the |Mojo...()| functions (declared in various
53 // mojo/public/c/include/mojo/system/*.h -- see those file for details on
54 // individual functions).
55 //
56 // The general guideline is functions that imply ownership transfer of a handle
57 // should take (or produce) an appropriate |Scoped...Handle|, while those that
58 // don't take a |...Handle|. For example, |CreateMessagePipe()| has two
59 // |ScopedMessagePipe| "out" parameters, whereas |Wait()| and |WaitMany()| take
60 // |Handle| parameters. Some, have both: e.g., |DuplicatedBuffer()| takes a
61 // suitable (unscoped) handle (e.g., |SharedBufferHandle|) "in" parameter and
62 // produces a suitable scoped handle (e.g., |ScopedSharedBufferHandle| a.k.a.
63 // |ScopedHandleBase<SharedBufferHandle>|) as an "out" parameter.
64 //
65 // An exception are some of the |...Raw()| functions. E.g., |CloseRaw()| takes a
66 // |Handle|, leaving the user to discard the wrapper.
67 //
68 // ScopedHandleBase ------------------------------------------------------------
69
70 // Scoper for the actual handle types defined further below. It's move-only,
71 // like the C++11 |unique_ptr|.
72 template <class HandleType>
73 class ScopedHandleBase {
74 public:
75 ScopedHandleBase() {}
76 explicit ScopedHandleBase(HandleType handle) : handle_(handle) {}
77 ~ScopedHandleBase() { CloseIfNecessary(); }
78
79 template <class CompatibleHandleType>
80 explicit ScopedHandleBase(ScopedHandleBase<CompatibleHandleType> other)
81 : handle_(other.release()) {}
82
83 // Move-only constructor and operator=.
84 ScopedHandleBase(ScopedHandleBase&& other) : handle_(other.release()) {}
85 ScopedHandleBase& operator=(ScopedHandleBase&& other) {
86 if (&other != this) {
87 CloseIfNecessary();
88 handle_ = other.release();
89 }
90 return *this;
91 }
92
93 const HandleType& get() const { return handle_; }
94
95 template <typename PassedHandleType>
96 static ScopedHandleBase<HandleType> From(
97 ScopedHandleBase<PassedHandleType> other) {
98 static_assert(
99 sizeof(static_cast<PassedHandleType*>(static_cast<HandleType*>(0))),
100 "HandleType is not a subtype of PassedHandleType");
101 return ScopedHandleBase<HandleType>(
102 static_cast<HandleType>(other.release().value()));
103 }
104
105 void swap(ScopedHandleBase& other) { handle_.swap(other.handle_); }
106
107 HandleType release() MOJO_WARN_UNUSED_RESULT {
108 HandleType rv;
109 rv.swap(handle_);
110 return rv;
111 }
112
113 void reset(HandleType handle = HandleType()) {
114 CloseIfNecessary();
115 handle_ = handle;
116 }
117
118 bool is_valid() const { return handle_.is_valid(); }
119
120 private:
121 void CloseIfNecessary() {
122 if (!handle_.is_valid())
123 return;
124 MojoResult result = MojoClose(handle_.value());
125 MOJO_ALLOW_UNUSED_LOCAL(result);
126 assert(result == MOJO_RESULT_OK);
127 }
128
129 HandleType handle_;
130
131 MOJO_MOVE_ONLY_TYPE(ScopedHandleBase);
132 };
133
134 template <typename HandleType>
135 inline ScopedHandleBase<HandleType> MakeScopedHandle(HandleType handle) {
136 return ScopedHandleBase<HandleType>(handle);
137 }
138
139 // Handle ----------------------------------------------------------------------
140
141 const MojoHandle kInvalidHandleValue = MOJO_HANDLE_INVALID;
142
143 // Wrapper base class for |MojoHandle|.
144 class Handle {
145 public:
146 Handle() : value_(kInvalidHandleValue) {}
147 explicit Handle(MojoHandle value) : value_(value) {}
148 ~Handle() {}
149
150 void swap(Handle& other) {
151 MojoHandle temp = value_;
152 value_ = other.value_;
153 other.value_ = temp;
154 }
155
156 bool is_valid() const { return value_ != kInvalidHandleValue; }
157
158 const MojoHandle& value() const { return value_; }
159 MojoHandle* mutable_value() { return &value_; }
160 void set_value(MojoHandle value) { value_ = value; }
161
162 private:
163 MojoHandle value_;
164
165 // Copying and assignment allowed.
166 };
167
168 // Should have zero overhead.
169 static_assert(sizeof(Handle) == sizeof(MojoHandle), "Bad size for C++ Handle");
170
171 // The scoper should also impose no more overhead.
172 typedef ScopedHandleBase<Handle> ScopedHandle;
173 static_assert(sizeof(ScopedHandle) == sizeof(Handle),
174 "Bad size for C++ ScopedHandle");
175
176 // |Close()| takes ownership of the handle, since it'll invalidate it.
177 // Note: There's nothing to do, since the argument will be destroyed when it
178 // goes out of scope.
179 template <class HandleType>
180 inline void Close(ScopedHandleBase<HandleType> /*handle*/) {}
181
182 // Most users should typically use |Close()| (above) instead.
183 inline MojoResult CloseRaw(Handle handle) {
184 return MojoClose(handle.value());
185 }
186
187 // Strict weak ordering, so that |Handle|s can be used as keys in |std::map|s,
188 inline bool operator<(const Handle a, const Handle b) {
189 return a.value() < b.value();
190 }
191
192 // Rights and duplication/replacement ------------------------------------------
193
194 // |handle| must be valid.
195 inline MojoHandleRights GetRights(Handle handle) {
196 assert(handle.is_valid());
197 MojoHandleRights rights = MOJO_HANDLE_RIGHT_NONE;
198 MojoResult result = MojoGetRights(handle.value(), &rights);
199 MOJO_ALLOW_UNUSED_LOCAL(result);
200 assert(result == MOJO_RESULT_OK);
201 return rights;
202 }
203
204 // |HandleType| should be some subclass of |Handle|; this is templated so that
205 // it will work with multiple handle types. |*handle| must be valid. Returns
206 // true on success or false on failure (in which case |*handle| is reset).
207 template <class HandleType>
208 inline bool ReplaceHandleWithReducedRights(ScopedHandleBase<HandleType>* handle,
209 MojoHandleRights rights_to_remove) {
210 assert(handle);
211 assert(handle->is_valid());
212 HandleType raw_handle = handle->release();
213 HandleType new_raw_handle;
214 if (MojoReplaceHandleWithReducedRights(raw_handle.value(), rights_to_remove,
215 new_raw_handle.mutable_value()) !=
216 MOJO_RESULT_OK) {
217 assert(false); // This really shouldn't happen.
218 CloseRaw(raw_handle);
219 return false;
220 }
221 // Otherwise, |raw_handle| is invalidated.
222 handle->reset(new_raw_handle);
223 return true;
224 }
225
226 template <class HandleType>
227 inline ScopedHandleBase<HandleType> DuplicateHandleWithReducedRights(
228 HandleType handle,
229 MojoHandleRights rights_to_remove) {
230 assert(handle.is_valid());
231 HandleType new_handle;
232 MojoResult result = MojoDuplicateHandleWithReducedRights(
233 handle.value(), rights_to_remove, new_handle.mutable_value());
234 MOJO_ALLOW_UNUSED_LOCAL(result);
235 assert(result == MOJO_RESULT_OK);
236 return MakeScopedHandle(new_handle);
237 }
238
239 template <class HandleType>
240 inline ScopedHandleBase<HandleType> DuplicateHandle(HandleType handle) {
241 HandleType new_handle;
242 MojoResult result =
243 MojoDuplicateHandle(handle.value(), new_handle.mutable_value());
244 MOJO_ALLOW_UNUSED_LOCAL(result);
245 assert(result == MOJO_RESULT_OK);
246 return MakeScopedHandle(new_handle);
247 }
248
249 } // namespace mojo
250
251 #endif // MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/system/data_pipe.h ('k') | mojo/public/cpp/system/macros.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698