Chromium Code Reviews| Index: base/files/scoped_platform_handle.h |
| diff --git a/base/files/scoped_platform_handle.h b/base/files/scoped_platform_handle.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c5f5ee2c26b9da89e19487789334e804077b8158 |
| --- /dev/null |
| +++ b/base/files/scoped_platform_handle.h |
| @@ -0,0 +1,164 @@ |
| +// Copyright 2017 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef BASE_FILES_SCOPED_PLATFORM_HANDLE_H_ |
| +#define BASE_FILES_SCOPED_PLATFORM_HANDLE_H_ |
| + |
| +#include <stddef.h> |
| +#include <stdint.h> |
| + |
| +#include "base/base_export.h" |
| +#include "build/build_config.h" |
| + |
| +#if defined(OS_WIN) |
| +#include <windows.h> |
| + |
| +#include "base/win/scoped_handle.h" |
| +#elif defined(OS_POSIX) |
| +#include "base/files/scoped_file.h" |
| +#endif |
| + |
| +#if defined(OS_MACOSX) && !defined(OS_IOS) |
| +#include <mach/mach.h> |
| + |
| +#include "base/mac/scoped_mach_port.h" |
| +#endif |
| + |
| +namespace base { |
| + |
| +// A ScopedPlatformHandle encapsulates ownership of one of various types of |
| +// platform-specific resource handles including POSIX file descriptors, Windows |
| +// handles, and Mach ports. |
| +// |
| +// The purpose of this type is to have a consistent representation of such |
| +// resources for the sake of safe ownership semantics, relegating |
| +// platform-specific details to either the code which initially acquires the |
| +// resource or the code which actually uses it. |
| +class BASE_EXPORT ScopedPlatformHandle { |
| + public: |
| + // The underlying type of the ScopedPlatformHandle. Note that the possible |
| + // values for this type are platform-dependent. |
| + enum class Type { |
| + INVALID, |
| +#if defined(OS_WIN) |
| + WINDOWS_HANDLE, |
| +#elif defined(OS_POSIX) |
| + FILE_DESCRIPTOR, |
| +#endif |
| +#if defined(OS_MACOSX) && !defined(OS_IOS) |
| + MACH_PORT_SEND, |
| + MACH_PORT_RECEIVE, |
| +#endif |
| + }; |
| + |
| + // Constructors for an invalid ScopedPlatformHandle of type |Type::INVALID|. |
| + ScopedPlatformHandle(); |
| + ScopedPlatformHandle(std::nullptr_t); |
| + |
| + ScopedPlatformHandle(ScopedPlatformHandle&& other); |
| + |
| +#if defined(OS_WIN) |
| + // Constructors which take ownership of a Windows handle. |
| + explicit ScopedPlatformHandle(HANDLE handle); |
| + explicit ScopedPlatformHandle(win::ScopedHandle handle) |
| +#elif defined(OS_POSIX) |
| + // Constructors which take ownership of a POSIX file descriptor. |
| + explicit ScopedPlatformHandle(int fd); |
| + explicit ScopedPlatformHandle(ScopedFD fd); |
| +#endif // defined(OS_WIN) |
| + |
| +#if defined(OS_MACOSX) && !defined(OS_IOS) |
| + // Constructors which take ownership of Mach port rights. The raw |
| + // |mach_port_t| version implies a send right. |
| + explicit ScopedPlatformHandle(mach_port_t port); |
| + explicit ScopedPlatformHandle(mac::ScopedMachSendRight port); |
| + explicit ScopedPlatformHandle(mac::ScopedMachReceiveRight port); |
| +#endif |
| + |
| + ~ScopedPlatformHandle(); |
| + |
| + ScopedPlatformHandle& operator=(ScopedPlatformHandle&& other); |
| + |
| + Type type() const { return type_; } |
| + |
| + // Indicates whether this ScopedPlatformHandle is valid. In order for a |
| + // ScopedPlatformHandle to be valid, its type must be something other than |
| + // |Type::INVALID|, and its value must reflect a valid value for that specific |
| + // type of handle. |
| + bool is_valid() const; |
| + |
| + // Closes the handle and resets the type to |Type::INVALID|. |
| + void reset(); |
| + |
| +#if defined(OS_WIN) |
| + // If this ScopedPlatformHandle is of type |Type::WINDOWS_HANDLE|, this |
| + // returns |true| and populates |*handle| with its value. Otherwise returns |
| + // |false|. |
| + bool GetAsWindowsHandle(HANDLE* handle) const; |
| + |
| + // Like GetAsWindowsHandle() above, but tranfers ownership. The |
| + // ScopedPlatformHandle is always reset to |Type::INVALID| after this call. |
| + bool TakeWindowsHandle(win::ScopedHandle* handle); |
| + |
| + // Like above, but transfers ownership to an unsafe unscoped type. |
| + bool ReleaseAsWindowsHandle(HANDLE* handle); |
| +#elif defined(OS_POSIX) |
| + // If this ScopedPlatformHandle is of type |Type::FILE_DESCRIPTOR|, this |
| + // returns |true| and populates |*fd| with its value. Otherwise returns |
| + // |false|. |
| + bool GetAsFileDescriptor(int* fd) const; |
| + |
| + // Like GetAsFileDescriptor() above, but transfers ownership. The |
| + // ScopedPlatformHandle is always reset to |Type::INVALID| after this call. |
| + bool TakeFileDescriptor(ScopedFD* fd); |
| + |
| + // Like above, but transfers ownership to an unsafe unscoped type. |
| + bool ReleaseAsFileDescriptor(int* fd); |
| +#endif |
| + |
| +#if defined(OS_MACOSX) && !defined(OS_IOS) |
| + // If this ScopedPlatformHandle is of type |Type::MACH_PORT_SEND| or |
| + // |Type::MACH_PORT_RECEIVE|, this returns |true| and populates |*port| with |
| + // its value. Otherwise returns |false|. |
| + bool GetAsMachPort(mach_port_t* port) const; |
| + |
| + // If this ScopedPlatformHandle is of type |Type::MACH_PORT_SEND| this returns |
| + // |true| and populates |*port| with its value. Otherwise returns |false|. The |
| + // ScopedPlatformHandle is always reset to |Type::INVALID| after this call. |
| + bool TakeMachPortSendRight(mac::ScopedMachSendRight* port); |
| + |
| + // If this ScopedPlatformHandle is of type |Type::MACH_PORT_RECEIVE| this |
| + // returns |true| and populates |*port| with its value. Otherwise returns |
| + // |false|. The ScopedPlatformHandle is always reset to |Type::INVALID| after |
| + // this call. |
| + bool TakeMachPortReceiveRight(mac::ScopedMachReceiveRight* port); |
| + |
| + // Like GetAsMachPort above, but transfers ownership to the unsafe, unscoped |
| + // |*port|. |
| + bool ReleaseAsMachPort(mach_port_t* port); |
| +#endif // defined(OS_MACOSX) && !defined(OS_IOS) |
| + |
| + private: |
| + Type type_; |
| + |
| + // NOTE: At most one of the fields below may be used at any given time, and |
| + // the one in use depends on the value of |type_|. We avoid using unified |
| + // storage here in order to leverage the existing scoping behavior of the |
| + // individual platform handle types. |
|
dcheng
2017/02/18 00:14:03
A C++11 union should still allow the existing scop
|
| + |
| +#if defined(OS_WIN) |
| + win::ScopedHandle windows_handle_; |
| +#elif defined(OS_POSIX) |
| + ScopedFD file_descriptor_; |
| +#endif |
| + |
| +#if defined(OS_MACOSX) && !defined(OS_IOS) |
| + mac::ScopedMachSendRight mach_port_send_; |
| + mac::ScopedMachReceiveRight mach_port_receive_; |
| +#endif |
| +}; |
| + |
| +} // namespace base |
| + |
| +#endif // BASE_FILES_SCOPED_PLATFORM_HANDLE_H_ |