OLD | NEW |
---|---|
(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 #ifndef BASE_FILES_SCOPED_PLATFORM_HANDLE_H_ | |
6 #define BASE_FILES_SCOPED_PLATFORM_HANDLE_H_ | |
7 | |
8 #include <stddef.h> | |
9 #include <stdint.h> | |
10 | |
11 #include "base/base_export.h" | |
12 #include "build/build_config.h" | |
13 | |
14 #if defined(OS_WIN) | |
15 #include <windows.h> | |
16 | |
17 #include "base/win/scoped_handle.h" | |
18 #elif defined(OS_POSIX) | |
19 #include "base/files/scoped_file.h" | |
20 #endif | |
21 | |
22 #if defined(OS_MACOSX) && !defined(OS_IOS) | |
23 #include <mach/mach.h> | |
24 | |
25 #include "base/mac/scoped_mach_port.h" | |
26 #endif | |
27 | |
28 namespace base { | |
29 | |
30 // A ScopedPlatformHandle encapsulates ownership of one of various types of | |
31 // platform-specific resource handles including POSIX file descriptors, Windows | |
32 // handles, and Mach ports. | |
33 // | |
34 // The purpose of this type is to have a consistent representation of such | |
35 // resources for the sake of safe ownership semantics, relegating | |
36 // platform-specific details to either the code which initially acquires the | |
37 // resource or the code which actually uses it. | |
38 class BASE_EXPORT ScopedPlatformHandle { | |
39 public: | |
40 // The underlying type of the ScopedPlatformHandle. Note that the possible | |
41 // values for this type are platform-dependent. | |
42 enum class Type { | |
43 INVALID, | |
44 #if defined(OS_WIN) | |
45 WINDOWS_HANDLE, | |
46 #elif defined(OS_POSIX) | |
47 FILE_DESCRIPTOR, | |
48 #endif | |
49 #if defined(OS_MACOSX) && !defined(OS_IOS) | |
50 MACH_PORT_SEND, | |
51 MACH_PORT_RECEIVE, | |
52 #endif | |
53 }; | |
54 | |
55 // Constructors for an invalid ScopedPlatformHandle of type |Type::INVALID|. | |
56 ScopedPlatformHandle(); | |
57 ScopedPlatformHandle(std::nullptr_t); | |
58 | |
59 ScopedPlatformHandle(ScopedPlatformHandle&& other); | |
60 | |
61 #if defined(OS_WIN) | |
62 // Constructors which take ownership of a Windows handle. | |
63 explicit ScopedPlatformHandle(HANDLE handle); | |
64 explicit ScopedPlatformHandle(win::ScopedHandle handle) | |
65 #elif defined(OS_POSIX) | |
66 // Constructors which take ownership of a POSIX file descriptor. | |
67 explicit ScopedPlatformHandle(int fd); | |
68 explicit ScopedPlatformHandle(ScopedFD fd); | |
69 #endif // defined(OS_WIN) | |
70 | |
71 #if defined(OS_MACOSX) && !defined(OS_IOS) | |
72 // Constructors which take ownership of Mach port rights. The raw | |
73 // |mach_port_t| version implies a send right. | |
74 explicit ScopedPlatformHandle(mach_port_t port); | |
75 explicit ScopedPlatformHandle(mac::ScopedMachSendRight port); | |
76 explicit ScopedPlatformHandle(mac::ScopedMachReceiveRight port); | |
77 #endif | |
78 | |
79 ~ScopedPlatformHandle(); | |
80 | |
81 ScopedPlatformHandle& operator=(ScopedPlatformHandle&& other); | |
82 | |
83 Type type() const { return type_; } | |
84 | |
85 // Indicates whether this ScopedPlatformHandle is valid. In order for a | |
86 // ScopedPlatformHandle to be valid, its type must be something other than | |
87 // |Type::INVALID|, and its value must reflect a valid value for that specific | |
88 // type of handle. | |
89 bool is_valid() const; | |
90 | |
91 // Closes the handle and resets the type to |Type::INVALID|. | |
92 void reset(); | |
93 | |
94 #if defined(OS_WIN) | |
95 // If this ScopedPlatformHandle is of type |Type::WINDOWS_HANDLE|, this | |
96 // returns |true| and populates |*handle| with its value. Otherwise returns | |
97 // |false|. | |
98 bool GetAsWindowsHandle(HANDLE* handle) const; | |
99 | |
100 // Like GetAsWindowsHandle() above, but tranfers ownership. The | |
101 // ScopedPlatformHandle is always reset to |Type::INVALID| after this call. | |
102 bool TakeWindowsHandle(win::ScopedHandle* handle); | |
103 | |
104 // Like above, but transfers ownership to an unsafe unscoped type. | |
105 bool ReleaseAsWindowsHandle(HANDLE* handle); | |
106 #elif defined(OS_POSIX) | |
107 // If this ScopedPlatformHandle is of type |Type::FILE_DESCRIPTOR|, this | |
108 // returns |true| and populates |*fd| with its value. Otherwise returns | |
109 // |false|. | |
110 bool GetAsFileDescriptor(int* fd) const; | |
111 | |
112 // Like GetAsFileDescriptor() above, but transfers ownership. The | |
113 // ScopedPlatformHandle is always reset to |Type::INVALID| after this call. | |
114 bool TakeFileDescriptor(ScopedFD* fd); | |
115 | |
116 // Like above, but transfers ownership to an unsafe unscoped type. | |
117 bool ReleaseAsFileDescriptor(int* fd); | |
118 #endif | |
119 | |
120 #if defined(OS_MACOSX) && !defined(OS_IOS) | |
121 // If this ScopedPlatformHandle is of type |Type::MACH_PORT_SEND| or | |
122 // |Type::MACH_PORT_RECEIVE|, this returns |true| and populates |*port| with | |
123 // its value. Otherwise returns |false|. | |
124 bool GetAsMachPort(mach_port_t* port) const; | |
125 | |
126 // If this ScopedPlatformHandle is of type |Type::MACH_PORT_SEND| this returns | |
127 // |true| and populates |*port| with its value. Otherwise returns |false|. The | |
128 // ScopedPlatformHandle is always reset to |Type::INVALID| after this call. | |
129 bool TakeMachPortSendRight(mac::ScopedMachSendRight* port); | |
130 | |
131 // If this ScopedPlatformHandle is of type |Type::MACH_PORT_RECEIVE| this | |
132 // returns |true| and populates |*port| with its value. Otherwise returns | |
133 // |false|. The ScopedPlatformHandle is always reset to |Type::INVALID| after | |
134 // this call. | |
135 bool TakeMachPortReceiveRight(mac::ScopedMachReceiveRight* port); | |
136 | |
137 // Like GetAsMachPort above, but transfers ownership to the unsafe, unscoped | |
138 // |*port|. | |
139 bool ReleaseAsMachPort(mach_port_t* port); | |
140 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | |
141 | |
142 private: | |
143 Type type_; | |
144 | |
145 // NOTE: At most one of the fields below may be used at any given time, and | |
146 // the one in use depends on the value of |type_|. We avoid using unified | |
147 // storage here in order to leverage the existing scoping behavior of the | |
148 // individual platform handle types. | |
dcheng
2017/02/18 00:14:03
A C++11 union should still allow the existing scop
| |
149 | |
150 #if defined(OS_WIN) | |
151 win::ScopedHandle windows_handle_; | |
152 #elif defined(OS_POSIX) | |
153 ScopedFD file_descriptor_; | |
154 #endif | |
155 | |
156 #if defined(OS_MACOSX) && !defined(OS_IOS) | |
157 mac::ScopedMachSendRight mach_port_send_; | |
158 mac::ScopedMachReceiveRight mach_port_receive_; | |
159 #endif | |
160 }; | |
161 | |
162 } // namespace base | |
163 | |
164 #endif // BASE_FILES_SCOPED_PLATFORM_HANDLE_H_ | |
OLD | NEW |