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

Unified 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 side-by-side diff with in-line comments
Download patch
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..a6528732ba7b9040f3a397fd2eb1b78b7bc31407
--- /dev/null
+++ b/base/files/scoped_platform_handle.cc
@@ -0,0 +1,241 @@
+// 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() {
+ reset();
+}
+
+ScopedPlatformHandle& ScopedPlatformHandle::operator=(
+ ScopedPlatformHandle&& other) {
+ // NOTE: It's important that we invoke the appropriate destructor here if
+ // necessary, since we may be transitioning from one handle type to another.
+ reset();
+
+ std::swap(type_, other.type_);
+
+ switch (type_) {
+ case Type::INVALID:
+ break;
+#if defined(OS_WIN)
+ case Type::WINDOWS_HANDLE:
+ new (&windows_handle_)
+ win::ScopedHandle(std::move(other.windows_handle_));
+ break;
+#elif defined(OS_POSIX)
+ case Type::FILE_DESCRIPTOR:
+ new (&file_descriptor_) ScopedFD(std::move(other.file_descriptor_));
+ break;
+#endif
+
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ case Type::MACH_PORT_SEND:
+ new (&mach_port_send_)
+ mac::ScopedMachSendRight(std::move(mach_port_send_));
+ break;
+ case Type::MACH_PORT_RECEIVE:
+ new (&mach_port_receive_)
+ mac::ScopedMachReceiveRight(std::move(mach_port_receive_));
+ break;
+#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
+ }
+
+ NOTREACHED();
+ return false;
+}
+
+void ScopedPlatformHandle::reset() {
+ switch (type_) {
+ case Type::INVALID:
+ break;
+#if defined(OS_WIN)
+ case Type::WINDOWS_HANDLE:
+ windows_handle_.~GenericScopedHandle();
+ break;
+#elif defined(OS_POSIX)
+ case Type::FILE_DESCRIPTOR:
+ file_descriptor_.~ScopedGeneric();
+ break;
+#endif
+
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ case Type::MACH_PORT_SEND:
+ mach_port_send_.~ScopedGeneric();
+ break;
+ case Type::MACH_PORT_RECEIVE:
+ mach_port_receive_.~ScopedGeneric();
+ break;
+#endif
+ }
+
+ type_ = Type::INVALID;
+}
+
+#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

Powered by Google App Engine
This is Rietveld 408576698