diff options
author | Alex Vakulenko <avakulenko@google.com> | 2016-03-21 10:06:21 -0700 |
---|---|---|
committer | Alex Vakulenko <avakulenko@google.com> | 2016-03-21 10:06:21 -0700 |
commit | 2b5c5fde012ebbc28208891aa7c95f3e13ce1d0a (patch) | |
tree | 4e37431482b959bfdac5a75c127f0a0f54107cc8 | |
parent | d8d95f24f51cea20a89e750b615909d1ad9e7081 (diff) | |
download | libchrome-2b5c5fde012ebbc28208891aa7c95f3e13ce1d0a.tar.gz |
libchrome: Add missing Mac files. Attempt 2android-n-preview-2
This is to fix an AOSP build break on Mac host.
Change-Id: I6c8e28ded5639b647a5674ea3da7d7401f71380b
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | base/memory/shared_memory_handle_mac.cc | 244 |
2 files changed, 245 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk index b04a942740..47ca1ac93a 100644 --- a/Android.mk +++ b/Android.mk @@ -238,6 +238,7 @@ libchromeMacSrc := \ base/mac/scoped_mach_vm.cc \ base/mac/scoped_nsautorelease_pool.mm \ base/memory/shared_memory_mac.cc \ + base/memory/shared_memory_handle_mac.cc \ base/message_loop/message_pump_mac.mm \ base/process/launch_mac.cc \ base/process/port_provider_mac.cc \ diff --git a/base/memory/shared_memory_handle_mac.cc b/base/memory/shared_memory_handle_mac.cc new file mode 100644 index 0000000000..600d2bb694 --- /dev/null +++ b/base/memory/shared_memory_handle_mac.cc @@ -0,0 +1,244 @@ +// Copyright 2015 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/memory/shared_memory_handle.h" + +#include <mach/mach_vm.h> +#include <stddef.h> +#include <sys/mman.h> +#include <unistd.h> + +#include "base/mac/mac_util.h" +#include "base/posix/eintr_wrapper.h" + +namespace base { + +static_assert(sizeof(SharedMemoryHandle::Type) <= + sizeof(SharedMemoryHandle::TypeWireFormat), + "Size of enum SharedMemoryHandle::Type exceeds size of type " + "transmitted over wire."); + +SharedMemoryHandle::SharedMemoryHandle() : type_(POSIX), file_descriptor_() {} + +SharedMemoryHandle::SharedMemoryHandle( + const base::FileDescriptor& file_descriptor) + : type_(POSIX), file_descriptor_(file_descriptor) {} + +SharedMemoryHandle::SharedMemoryHandle(int fd, bool auto_close) + : type_(POSIX), file_descriptor_(fd, auto_close) {} + +SharedMemoryHandle::SharedMemoryHandle(mach_vm_size_t size) { + type_ = MACH; + mach_port_t named_right; + kern_return_t kr = mach_make_memory_entry_64( + mach_task_self(), + &size, + 0, // Address. + MAP_MEM_NAMED_CREATE | VM_PROT_READ | VM_PROT_WRITE, + &named_right, + MACH_PORT_NULL); // Parent handle. + if (kr != KERN_SUCCESS) { + memory_object_ = MACH_PORT_NULL; + return; + } + + memory_object_ = named_right; + size_ = size; + pid_ = GetCurrentProcId(); + ownership_passes_to_ipc_ = false; +} + +SharedMemoryHandle::SharedMemoryHandle(mach_port_t memory_object, + mach_vm_size_t size, + base::ProcessId pid) + : type_(MACH), + memory_object_(memory_object), + size_(size), + pid_(pid), + ownership_passes_to_ipc_(false) {} + +SharedMemoryHandle::SharedMemoryHandle(const SharedMemoryHandle& handle) + : type_(handle.type_) { + CopyRelevantData(handle); +} + +SharedMemoryHandle& SharedMemoryHandle::operator=( + const SharedMemoryHandle& handle) { + if (this == &handle) + return *this; + + type_ = handle.type_; + CopyRelevantData(handle); + return *this; +} + +SharedMemoryHandle SharedMemoryHandle::Duplicate() const { + switch (type_) { + case POSIX: { + if (!IsValid()) + return SharedMemoryHandle(); + + int duped_fd = HANDLE_EINTR(dup(file_descriptor_.fd)); + if (duped_fd < 0) + return SharedMemoryHandle(); + return SharedMemoryHandle(duped_fd, true); + } + case MACH: { + if (!IsValid()) + return SharedMemoryHandle(MACH_PORT_NULL, 0, 0); + + // Increment the ref count. + kern_return_t kr = mach_port_mod_refs(mach_task_self(), memory_object_, + MACH_PORT_RIGHT_SEND, 1); + DCHECK_EQ(kr, KERN_SUCCESS); + SharedMemoryHandle handle(*this); + handle.SetOwnershipPassesToIPC(true); + return handle; + } + } +} + +bool SharedMemoryHandle::operator==(const SharedMemoryHandle& handle) const { + if (!IsValid() && !handle.IsValid()) + return true; + + if (type_ != handle.type_) + return false; + + switch (type_) { + case POSIX: + return file_descriptor_ == handle.file_descriptor_; + case MACH: + return memory_object_ == handle.memory_object_ && size_ == handle.size_ && + pid_ == handle.pid_; + } +} + +bool SharedMemoryHandle::operator!=(const SharedMemoryHandle& handle) const { + return !(*this == handle); +} + +SharedMemoryHandle::Type SharedMemoryHandle::GetType() const { + return type_; +} + +bool SharedMemoryHandle::IsValid() const { + switch (type_) { + case POSIX: + return file_descriptor_.fd >= 0; + case MACH: + return memory_object_ != MACH_PORT_NULL; + } +} + +void SharedMemoryHandle::SetFileHandle(int fd, bool auto_close) { + DCHECK(!IsValid()); + file_descriptor_.fd = fd; + file_descriptor_.auto_close = auto_close; + type_ = POSIX; +} + +const FileDescriptor SharedMemoryHandle::GetFileDescriptor() const { + DCHECK_EQ(type_, POSIX); + return file_descriptor_; +} + +mach_port_t SharedMemoryHandle::GetMemoryObject() const { + DCHECK_EQ(type_, MACH); + return memory_object_; +} + +bool SharedMemoryHandle::GetSize(size_t* size) const { + if (!IsValid()) + return false; + + switch (type_) { + case SharedMemoryHandle::POSIX: + struct stat st; + if (fstat(file_descriptor_.fd, &st) != 0) + return false; + if (st.st_size < 0) + return false; + *size = st.st_size; + return true; + case SharedMemoryHandle::MACH: + *size = size_; + return true; + } +} + +bool SharedMemoryHandle::MapAt(off_t offset, + size_t bytes, + void** memory, + bool read_only) { + DCHECK(IsValid()); + switch (type_) { + case SharedMemoryHandle::POSIX: + *memory = mmap(nullptr, bytes, PROT_READ | (read_only ? 0 : PROT_WRITE), + MAP_SHARED, file_descriptor_.fd, offset); + + return *memory && *memory != reinterpret_cast<void*>(-1); + case SharedMemoryHandle::MACH: + // The flag VM_PROT_IS_MASK is only supported on OSX 10.7+. + DCHECK(mac::IsOSLionOrLater()); + + DCHECK_EQ(pid_, GetCurrentProcId()); + kern_return_t kr = mach_vm_map( + mach_task_self(), + reinterpret_cast<mach_vm_address_t*>(memory), // Output parameter + bytes, + 0, // Alignment mask + VM_FLAGS_ANYWHERE, + memory_object_, + offset, + FALSE, // Copy + VM_PROT_READ | (read_only ? 0 : VM_PROT_WRITE), // Current protection + VM_PROT_WRITE | VM_PROT_READ | VM_PROT_IS_MASK, // Maximum protection + VM_INHERIT_NONE); + return kr == KERN_SUCCESS; + } +} + +void SharedMemoryHandle::Close() const { + if (!IsValid()) + return; + + switch (type_) { + case POSIX: + if (IGNORE_EINTR(close(file_descriptor_.fd)) < 0) + DPLOG(ERROR) << "Error closing fd."; + break; + case MACH: + kern_return_t kr = mach_port_deallocate(mach_task_self(), memory_object_); + if (kr != KERN_SUCCESS) + DPLOG(ERROR) << "Error deallocating mach port: " << kr; + break; + } +} + +void SharedMemoryHandle::SetOwnershipPassesToIPC(bool ownership_passes) { + DCHECK_EQ(type_, MACH); + ownership_passes_to_ipc_ = ownership_passes; +} + +bool SharedMemoryHandle::OwnershipPassesToIPC() const { + DCHECK_EQ(type_, MACH); + return ownership_passes_to_ipc_; +} + +void SharedMemoryHandle::CopyRelevantData(const SharedMemoryHandle& handle) { + switch (type_) { + case POSIX: + file_descriptor_ = handle.file_descriptor_; + break; + case MACH: + memory_object_ = handle.memory_object_; + size_ = handle.size_; + pid_ = handle.pid_; + ownership_passes_to_ipc_ = handle.ownership_passes_to_ipc_; + break; + } +} + +} // namespace base |