Chromium Code Reviews| 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 |