| Index: base/files/scoped_platform_handle.cc
|
| diff --git a/base/files/scoped_platform_handle.cc b/base/files/scoped_platform_handle.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ada84c8cf04e8e04651fdc3e2071f65e04d2fdce
|
| --- /dev/null
|
| +++ b/base/files/scoped_platform_handle.cc
|
| @@ -0,0 +1,230 @@
|
| +// 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.
|
| +
|
| +#include "base/files/scoped_platform_handle.h"
|
| +
|
| +#include "base/logging.h"
|
| +
|
| +namespace base {
|
| +
|
| +ScopedPlatformHandle::ScopedPlatformHandle() : ScopedPlatformHandle(nullptr) {}
|
| +
|
| +ScopedPlatformHandle::ScopedPlatformHandle(std::nullptr_t)
|
| + : type_(Type::INVALID) {}
|
| +
|
| +ScopedPlatformHandle::ScopedPlatformHandle(ScopedPlatformHandle&& other) {
|
| + *this = std::move(other);
|
| +}
|
| +
|
| +#if defined(OS_WIN)
|
| +ScopedPlatformHandle::ScopedPlatformHandle(HANDLE handle)
|
| + : type_(Type::WINDOWS_HANDLE), windows_handle_(handle) {}
|
| +
|
| +ScopedPlatformHandle::ScopedPlatformHandle(win::ScopedHandle handle)
|
| + : type_(Type::WINDOWS_HANDLE), windows_handle_(std::move(handle)) {}
|
| +
|
| +#elif defined(OS_POSIX)
|
| +
|
| +ScopedPlatformHandle::ScopedPlatformHandle(int fd)
|
| + : type_(Type::FILE_DESCRIPTOR), file_descriptor_(fd) {}
|
| +
|
| +ScopedPlatformHandle::ScopedPlatformHandle(ScopedFD fd)
|
| + : type_(Type::FILE_DESCRIPTOR), file_descriptor_(std::move(fd)) {}
|
| +
|
| +#endif // defined(OS_WIN)
|
| +
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| +
|
| +ScopedPlatformHandle::ScopedPlatformHandle(mach_port_t port)
|
| + : type_(Type::MACH_PORT_SEND), mach_port_send_(port) {}
|
| +
|
| +ScopedPlatformHandle::ScopedPlatformHandle(mac::ScopedMachSendRight port)
|
| + : type_(Type::MACH_PORT_SEND), mach_port_send_(std::move(port)) {}
|
| +
|
| +ScopedPlatformHandle::ScopedPlatformHandle(mac::ScopedMachReceiveRight port)
|
| + : type_(Type::MACH_PORT_RECEIVE), mach_port_receive_(std::move(port)) {}
|
| +
|
| +#endif // defined(OS_MACOSX) && !defined(OS_IOS)
|
| +
|
| +ScopedPlatformHandle::~ScopedPlatformHandle() {}
|
| +
|
| +ScopedPlatformHandle& ScopedPlatformHandle::operator=(
|
| + ScopedPlatformHandle&& other) {
|
| + type_ = other.type_;
|
| + other.type_ = Type::INVALID;
|
| +
|
| +#if defined(OS_WIN)
|
| + windows_handle_ = std::move(other.windows_handle_);
|
| +#elif defined(OS_POSIX)
|
| + file_descriptor_ = std::move(other.file_descriptor_);
|
| +#endif
|
| +
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| + mach_port_send_ = std::move(other.mach_port_send_);
|
| + mach_port_receive_ = std::move(other.mach_port_receive_);
|
| +#endif
|
| +
|
| + return *this;
|
| +}
|
| +
|
| +bool ScopedPlatformHandle::is_valid() const {
|
| + switch (type_) {
|
| + case Type::INVALID:
|
| + return false;
|
| +
|
| +#if defined(OS_WIN)
|
| + case Type::WINDOWS_HANDLE:
|
| + return windows_handle_.IsValid();
|
| +#elif defined(OS_POSIX)
|
| + case Type::FILE_DESCRIPTOR:
|
| + return file_descriptor_.is_valid();
|
| +#endif
|
| +
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| + case Type::MACH_PORT_SEND:
|
| + return mach_port_send_.is_valid();
|
| + case Type::MACH_PORT_RECEIVE:
|
| + return mach_port_receive_.is_valid();
|
| +#endif
|
| + }
|
| +}
|
| +
|
| +void ScopedPlatformHandle::reset() {
|
| + switch (type_) {
|
| + case Type::INVALID:
|
| + return;
|
| +
|
| +#if defined(OS_WIN)
|
| + case Type::WINDOWS_HANDLE:
|
| + windows_handle_.Close();
|
| + break;
|
| +#elif defined(OS_POSIX)
|
| + case Type::FILE_DESCRIPTOR:
|
| + file_descriptor_.reset();
|
| + break;
|
| +#endif
|
| +
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| + case Type::MACH_PORT_SEND:
|
| + mach_port_send_.reset();
|
| + break;
|
| + case Type::MACH_PORT_RECEIVE:
|
| + mach_port_receive_.reset();
|
| + break;
|
| +#endif
|
| + }
|
| +
|
| + type_ = Type::INVALID;
|
| +
|
| +#if defined(OS_WIN)
|
| + DCHECK(!windows_handle_.IsValid());
|
| +#elif defined(OS_POSIX)
|
| + DCHECK(!file_descriptor_.is_valid());
|
| +#endif
|
| +
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| + DCHECK(!mach_port_send_.is_valid());
|
| + DCHECK(!mach_port_receive_.is_valid());
|
| +#endif
|
| +}
|
| +
|
| +#if defined(OS_WIN)
|
| +
|
| +bool ScopedPlatformHandle::GetAsWindowsHandle(HANDLE* handle) const {
|
| + if (type_ != Type::WINDOWS_HANDLE)
|
| + return false;
|
| + *handle = windows_handle_.Get();
|
| + return true;
|
| +}
|
| +
|
| +bool ScopedPlatformHandle::TakeWindowsHandle(win::ScopedHandle* handle) {
|
| + if (type_ != Type::WINDOWS_HANDLE)
|
| + return false;
|
| + *handle = std::move(windows_handle_);
|
| + type_ = Type::INVALID;
|
| + return true;
|
| +}
|
| +
|
| +bool ScopedPlatformHandle::ReleaseAsWindowsHandle(HANDLE* handle) {
|
| + if (type_ != Type::WINDOWS_HANDLE)
|
| + return false;
|
| + *handle = windows_handle_.Take();
|
| + type_ = Type::INVALID;
|
| + return true;
|
| +}
|
| +
|
| +#elif defined(OS_POSIX)
|
| +
|
| +bool ScopedPlatformHandle::GetAsFileDescriptor(int* fd) const {
|
| + if (type_ != Type::FILE_DESCRIPTOR)
|
| + return false;
|
| + *fd = file_descriptor_.get();
|
| + return true;
|
| +}
|
| +
|
| +bool ScopedPlatformHandle::TakeFileDescriptor(ScopedFD* fd) {
|
| + if (type_ != Type::FILE_DESCRIPTOR)
|
| + return false;
|
| + *fd = std::move(file_descriptor_);
|
| + type_ = Type::INVALID;
|
| + return true;
|
| +}
|
| +
|
| +bool ScopedPlatformHandle::ReleaseAsFileDescriptor(int* fd) {
|
| + if (type_ != Type::FILE_DESCRIPTOR)
|
| + return false;
|
| + *fd = file_descriptor_.release();
|
| + type_ = Type::INVALID;
|
| + return true;
|
| +}
|
| +
|
| +#endif // defined(OS_WIN)
|
| +
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| +
|
| +bool ScopedPlatformHandle::GetAsMachPort(mach_port_t* port) const {
|
| + if (type_ == Type::MACH_PORT_SEND) {
|
| + *port = mach_port_send_.get();
|
| + return true;
|
| + } else if (type_ == Type::MACH_PORT_RECEIVE) {
|
| + *port = mach_port_receive_.get();
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +bool ScopedPlatformHandle::TakeMachPortSendRight(
|
| + mac::ScopedMachSendRight* port) {
|
| + if (type_ != Type::MACH_PORT_SEND)
|
| + return false;
|
| + *port = std::move(mach_port_send_);
|
| + type_ = Type::INVALID;
|
| + return true;
|
| +}
|
| +
|
| +bool ScopedPlatformHandle::TakeMachPortReceiveRight(
|
| + mac::ScopedMachReceiveRight* port) {
|
| + if (type_ != Type::MACH_PORT_RECEIVE)
|
| + return false;
|
| + *port = std::move(mach_port_receive_);
|
| + type_ = Type::INVALID;
|
| + return true;
|
| +}
|
| +
|
| +bool ScopedPlatformHandle::ReleaseAsMachPort(mach_port_t* port) {
|
| + if (type_ == Type::MACH_PORT_SEND) {
|
| + *port = mach_port_send_.release();
|
| + type_ = Type::INVALID;
|
| + return true;
|
| + } else if (type_ == Type::MACH_PORT_RECEIVE) {
|
| + *port = mach_port_receive_.release();
|
| + type_ = Type::INVALID;
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +#endif // defined(OS_MACOSX) && !defined(OS_IOS)
|
| +
|
| +} // namespace base
|
|
|