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

Side by Side Diff: base/files/scoped_platform_handle.cc

Issue 2705743002: Introduce base::ScopedPlatformHandle (Closed)
Patch Set: . Created 3 years, 10 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
OLDNEW
(Empty)
1 // Copyright 2017 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 #include "base/files/scoped_platform_handle.h"
6
7 #include "base/logging.h"
8
9 namespace base {
10
11 ScopedPlatformHandle::ScopedPlatformHandle() : ScopedPlatformHandle(nullptr) {}
12
13 ScopedPlatformHandle::ScopedPlatformHandle(std::nullptr_t)
14 : type_(Type::INVALID) {}
15
16 ScopedPlatformHandle::ScopedPlatformHandle(ScopedPlatformHandle&& other) {
17 *this = std::move(other);
18 }
19
20 #if defined(OS_WIN)
21 ScopedPlatformHandle::ScopedPlatformHandle(HANDLE handle)
22 : type_(Type::WINDOWS_HANDLE), windows_handle_(handle) {}
23
24 ScopedPlatformHandle::ScopedPlatformHandle(win::ScopedHandle handle)
25 : type_(Type::WINDOWS_HANDLE), windows_handle_(std::move(handle)) {}
26
27 #elif defined(OS_POSIX)
28
29 ScopedPlatformHandle::ScopedPlatformHandle(int fd)
30 : type_(Type::FILE_DESCRIPTOR), file_descriptor_(fd) {}
31
32 ScopedPlatformHandle::ScopedPlatformHandle(ScopedFD fd)
33 : type_(Type::FILE_DESCRIPTOR), file_descriptor_(std::move(fd)) {}
34
35 #endif // defined(OS_WIN)
36
37 #if defined(OS_MACOSX) && !defined(OS_IOS)
38
39 ScopedPlatformHandle::ScopedPlatformHandle(mach_port_t port)
40 : type_(Type::MACH_PORT_SEND), mach_port_send_(port) {}
41
42 ScopedPlatformHandle::ScopedPlatformHandle(mac::ScopedMachSendRight port)
43 : type_(Type::MACH_PORT_SEND), mach_port_send_(std::move(port)) {}
44
45 ScopedPlatformHandle::ScopedPlatformHandle(mac::ScopedMachReceiveRight port)
46 : type_(Type::MACH_PORT_RECEIVE), mach_port_receive_(std::move(port)) {}
47
48 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
49
50 ScopedPlatformHandle::~ScopedPlatformHandle() {
51 reset();
52 }
53
54 ScopedPlatformHandle& ScopedPlatformHandle::operator=(
55 ScopedPlatformHandle&& other) {
56 // NOTE: It's important that we invoke the appropriate destructor here if
57 // necessary, since we may be transitioning from one handle type to another.
58 reset();
59
60 std::swap(type_, other.type_);
61
62 switch (type_) {
63 case Type::INVALID:
64 break;
65 #if defined(OS_WIN)
66 case Type::WINDOWS_HANDLE:
67 new (&windows_handle_)
68 win::ScopedHandle(std::move(other.windows_handle_));
69 break;
70 #elif defined(OS_POSIX)
71 case Type::FILE_DESCRIPTOR:
72 new (&file_descriptor_) ScopedFD(std::move(other.file_descriptor_));
73 break;
74 #endif
75
76 #if defined(OS_MACOSX) && !defined(OS_IOS)
77 case Type::MACH_PORT_SEND:
78 new (&mach_port_send_)
79 mac::ScopedMachSendRight(std::move(mach_port_send_));
80 break;
81 case Type::MACH_PORT_RECEIVE:
82 new (&mach_port_receive_)
83 mac::ScopedMachReceiveRight(std::move(mach_port_receive_));
84 break;
85 #endif
86 }
87
88 return *this;
89 }
90
91 bool ScopedPlatformHandle::is_valid() const {
92 switch (type_) {
93 case Type::INVALID:
94 return false;
95
96 #if defined(OS_WIN)
97 case Type::WINDOWS_HANDLE:
98 return windows_handle_.IsValid();
99 #elif defined(OS_POSIX)
100 case Type::FILE_DESCRIPTOR:
101 return file_descriptor_.is_valid();
102 #endif
103
104 #if defined(OS_MACOSX) && !defined(OS_IOS)
105 case Type::MACH_PORT_SEND:
106 return mach_port_send_.is_valid();
107 case Type::MACH_PORT_RECEIVE:
108 return mach_port_receive_.is_valid();
109 #endif
110 }
111
112 NOTREACHED();
113 return false;
114 }
115
116 void ScopedPlatformHandle::reset() {
117 switch (type_) {
118 case Type::INVALID:
119 break;
120 #if defined(OS_WIN)
121 case Type::WINDOWS_HANDLE:
122 windows_handle_.~GenericScopedHandle();
123 break;
124 #elif defined(OS_POSIX)
125 case Type::FILE_DESCRIPTOR:
126 file_descriptor_.~ScopedGeneric();
127 break;
128 #endif
129
130 #if defined(OS_MACOSX) && !defined(OS_IOS)
131 case Type::MACH_PORT_SEND:
132 mach_port_send_.~ScopedGeneric();
133 break;
134 case Type::MACH_PORT_RECEIVE:
135 mach_port_receive_.~ScopedGeneric();
136 break;
137 #endif
138 }
139
140 type_ = Type::INVALID;
141 }
142
143 #if defined(OS_WIN)
144
145 bool ScopedPlatformHandle::GetAsWindowsHandle(HANDLE* handle) const {
146 if (type_ != Type::WINDOWS_HANDLE)
147 return false;
148 *handle = windows_handle_.Get();
149 return true;
150 }
151
152 bool ScopedPlatformHandle::TakeWindowsHandle(win::ScopedHandle* handle) {
153 if (type_ != Type::WINDOWS_HANDLE)
154 return false;
155 *handle = std::move(windows_handle_);
156 type_ = Type::INVALID;
157 return true;
158 }
159
160 bool ScopedPlatformHandle::ReleaseAsWindowsHandle(HANDLE* handle) {
161 if (type_ != Type::WINDOWS_HANDLE)
162 return false;
163 *handle = windows_handle_.Take();
164 type_ = Type::INVALID;
165 return true;
166 }
167
168 #elif defined(OS_POSIX)
169
170 bool ScopedPlatformHandle::GetAsFileDescriptor(int* fd) const {
171 if (type_ != Type::FILE_DESCRIPTOR)
172 return false;
173 *fd = file_descriptor_.get();
174 return true;
175 }
176
177 bool ScopedPlatformHandle::TakeFileDescriptor(ScopedFD* fd) {
178 if (type_ != Type::FILE_DESCRIPTOR)
179 return false;
180 *fd = std::move(file_descriptor_);
181 type_ = Type::INVALID;
182 return true;
183 }
184
185 bool ScopedPlatformHandle::ReleaseAsFileDescriptor(int* fd) {
186 if (type_ != Type::FILE_DESCRIPTOR)
187 return false;
188 *fd = file_descriptor_.release();
189 type_ = Type::INVALID;
190 return true;
191 }
192
193 #endif // defined(OS_WIN)
194
195 #if defined(OS_MACOSX) && !defined(OS_IOS)
196
197 bool ScopedPlatformHandle::GetAsMachPort(mach_port_t* port) const {
198 if (type_ == Type::MACH_PORT_SEND) {
199 *port = mach_port_send_.get();
200 return true;
201 } else if (type_ == Type::MACH_PORT_RECEIVE) {
202 *port = mach_port_receive_.get();
203 return true;
204 }
205 return false;
206 }
207
208 bool ScopedPlatformHandle::TakeMachPortSendRight(
209 mac::ScopedMachSendRight* port) {
210 if (type_ != Type::MACH_PORT_SEND)
211 return false;
212 *port = std::move(mach_port_send_);
213 type_ = Type::INVALID;
214 return true;
215 }
216
217 bool ScopedPlatformHandle::TakeMachPortReceiveRight(
218 mac::ScopedMachReceiveRight* port) {
219 if (type_ != Type::MACH_PORT_RECEIVE)
220 return false;
221 *port = std::move(mach_port_receive_);
222 type_ = Type::INVALID;
223 return true;
224 }
225
226 bool ScopedPlatformHandle::ReleaseAsMachPort(mach_port_t* port) {
227 if (type_ == Type::MACH_PORT_SEND) {
228 *port = mach_port_send_.release();
229 type_ = Type::INVALID;
230 return true;
231 } else if (type_ == Type::MACH_PORT_RECEIVE) {
232 *port = mach_port_receive_.release();
233 type_ = Type::INVALID;
234 return true;
235 }
236 return false;
237 }
238
239 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
240
241 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698