Commit b0cfc3f3 authored by Robert Sesek's avatar Robert Sesek Committed by Commit Bot

[Mac] Remove FD-backed shared memory implementation.

There are no more users of this implementation, and the new shared
memory APIs do not support FD-backed shared memory on Mac.

Bug: 776564
Change-Id: I9307a6e46daa4329f0d04e6951b6e432a79c2c47
Reviewed-on: https://chromium-review.googlesource.com/c/1303873Reviewed-by: default avatarAlexandr Ilin <alexilin@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Robert Sesek <rsesek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#603757}
parent 80a6ad7c
......@@ -57,7 +57,6 @@ PlatformSharedMemoryRegion::TakeFromSharedMemoryHandle(
const SharedMemoryHandle& handle,
Mode mode) {
CHECK(mode == Mode::kReadOnly || mode == Mode::kUnsafe);
CHECK(handle.GetType() == SharedMemoryHandle::MACH);
if (!handle.IsValid())
return {};
......
......@@ -36,10 +36,7 @@ class FilePath;
// Options for creating a shared memory object.
struct BASE_EXPORT SharedMemoryCreateOptions {
#if defined(OS_MACOSX) && !defined(OS_IOS)
// The type of OS primitive that should back the SharedMemory object.
SharedMemoryHandle::Type type = SharedMemoryHandle::MACH;
#elif !defined(OS_FUCHSIA)
#if !defined(OS_FUCHSIA)
// DEPRECATED (crbug.com/345734):
// If NULL, the object is anonymous. This pointer is owned by the caller
// and must live through the call to Create().
......@@ -51,7 +48,7 @@ struct BASE_EXPORT SharedMemoryCreateOptions {
// shared memory must not exist. This flag is meaningless unless
// name_deprecated is non-NULL.
bool open_existing_deprecated = false;
#endif // defined(OS_MACOSX) && !defined(OS_IOS)
#endif
// Size of the shared memory object to be created.
// When opening an existing object, this has no effect.
......@@ -106,7 +103,7 @@ class BASE_EXPORT SharedMemory {
// primitive.
static SharedMemoryHandle DuplicateHandle(const SharedMemoryHandle& handle);
#if defined(OS_POSIX)
#if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS))
// This method requires that the SharedMemoryHandle is backed by a POSIX fd.
static int GetFdFromSharedMemoryHandle(const SharedMemoryHandle& handle);
#endif
......@@ -231,12 +228,6 @@ class BASE_EXPORT SharedMemory {
SharedMemoryHandle readonly_shm_;
#endif
#if defined(OS_MACOSX) && !defined(OS_IOS)
// The mechanism by which the memory is mapped. Only valid if |memory_| is not
// |nullptr|.
SharedMemoryHandle::Type mapped_memory_mechanism_ = SharedMemoryHandle::MACH;
#endif
// The OS primitive that backs the shared memory region.
SharedMemoryHandle shm_;
......
......@@ -16,7 +16,6 @@
#elif defined(OS_MACOSX) && !defined(OS_IOS)
#include <mach/mach.h>
#include "base/base_export.h"
#include "base/file_descriptor_posix.h"
#include "base/macros.h"
#include "base/process/process_handle.h"
#elif defined(OS_POSIX)
......@@ -101,13 +100,6 @@ class BASE_EXPORT SharedMemoryHandle {
const base::UnguessableToken& guid);
zx_handle_t GetHandle() const;
#elif defined(OS_MACOSX) && !defined(OS_IOS)
enum Type {
// The SharedMemoryHandle is backed by a POSIX fd.
POSIX,
// The SharedMemoryHandle is backed by the Mach primitive "memory object".
MACH,
};
// Makes a Mach-based SharedMemoryHandle of the given size. On error,
// subsequent calls to IsValid() return false.
// Passing the wrong |size| has no immediate consequence, but may cause errors
......@@ -122,8 +114,6 @@ class BASE_EXPORT SharedMemoryHandle {
mach_vm_size_t size,
const base::UnguessableToken& guid);
Type GetType() const { return type_; }
// Exposed so that the SharedMemoryHandle can be transported between
// processes.
mach_port_t GetMemoryObject() const;
......@@ -165,7 +155,7 @@ class BASE_EXPORT SharedMemoryHandle {
bool SetRegionReadOnly() const;
#endif
#if defined(OS_POSIX)
#if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS))
// Constructs a SharedMemoryHandle backed by a FileDescriptor. The newly
// created instance has the same ownership semantics as base::FileDescriptor.
// This typically means that the SharedMemoryHandle takes ownership of the
......@@ -203,23 +193,13 @@ class BASE_EXPORT SharedMemoryHandle {
friend bool CheckReadOnlySharedMemoryHandleForTesting(
SharedMemoryHandle handle);
Type type_ = MACH;
// Each instance of a SharedMemoryHandle is backed either by a POSIX fd or a
// mach port. |type_| determines the backing member.
union {
FileDescriptor file_descriptor_;
mach_port_t memory_object_ = MACH_PORT_NULL;
struct {
mach_port_t memory_object_ = MACH_PORT_NULL;
// Whether passing this object as a parameter to an IPC message passes
// ownership of |memory_object_| to the IPC stack. This is meant to mimic
// the behavior of the |auto_close| parameter of FileDescriptor.
// Defaults to |false|.
bool ownership_passes_to_ipc_ = false;
};
};
// Whether passing this object as a parameter to an IPC message passes
// ownership of |memory_object_| to the IPC stack. This is meant to mimic
// the behavior of the |auto_close| parameter of FileDescriptor.
// Defaults to |false|.
bool ownership_passes_to_ipc_ = false;
#elif defined(OS_ANDROID)
friend class SharedMemory;
......
......@@ -6,30 +6,17 @@
#include <mach/mach_vm.h>
#include <stddef.h>
#include <sys/mman.h>
#include <unistd.h>
#include "base/mac/mac_util.h"
#include "base/mac/mach_logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/unguessable_token.h"
namespace base {
SharedMemoryHandle::SharedMemoryHandle() {}
SharedMemoryHandle::SharedMemoryHandle(
const base::FileDescriptor& file_descriptor,
size_t size,
const base::UnguessableToken& guid)
: type_(POSIX),
file_descriptor_(file_descriptor),
guid_(guid),
size_(size) {}
SharedMemoryHandle::SharedMemoryHandle(mach_vm_size_t size,
const base::UnguessableToken& guid) {
type_ = MACH;
mach_port_t named_right;
kern_return_t kr = mach_make_memory_entry_64(
mach_task_self(),
......@@ -52,48 +39,29 @@ SharedMemoryHandle::SharedMemoryHandle(mach_vm_size_t size,
SharedMemoryHandle::SharedMemoryHandle(mach_port_t memory_object,
mach_vm_size_t size,
const base::UnguessableToken& guid)
: type_(MACH),
memory_object_(memory_object),
: memory_object_(memory_object),
ownership_passes_to_ipc_(false),
guid_(guid),
size_(size) {}
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(FileDescriptor(duped_fd, true), size_, guid_);
}
case MACH: {
if (!IsValid())
return SharedMemoryHandle();
// 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;
}
}
if (!IsValid())
return SharedMemoryHandle();
// 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::IsValid() const {
switch (type_) {
case POSIX:
return file_descriptor_.fd >= 0;
case MACH:
return memory_object_ != MACH_PORT_NULL;
}
return memory_object_ != MACH_PORT_NULL;
}
mach_port_t SharedMemoryHandle::GetMemoryObject() const {
DCHECK_EQ(type_, MACH);
return memory_object_;
}
......@@ -102,52 +70,32 @@ bool SharedMemoryHandle::MapAt(off_t offset,
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 != MAP_FAILED;
case SharedMemoryHandle::MACH:
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;
}
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)
MACH_DLOG(ERROR, kr) << "Error deallocating mach port";
break;
}
kern_return_t kr = mach_port_deallocate(mach_task_self(), memory_object_);
MACH_DLOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "Error deallocating mach port";
}
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_;
}
......
......@@ -11,8 +11,6 @@
#include <sys/stat.h>
#include <unistd.h>
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
......@@ -21,12 +19,10 @@
#include "base/memory/shared_memory_tracker.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "base/posix/eintr_wrapper.h"
#include "base/posix/safe_strerror.h"
#include "base/process/process_metrics.h"
#include "base/scoped_generic.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
......@@ -85,9 +81,7 @@ bool MakeMachSharedMemoryHandleReadOnly(SharedMemoryHandle* new_handle,
SharedMemory::SharedMemory() {}
SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only)
: mapped_memory_mechanism_(SharedMemoryHandle::POSIX),
shm_(handle),
read_only_(read_only) {}
: shm_(handle), read_only_(read_only) {}
SharedMemory::~SharedMemory() {
Unmap();
......@@ -115,12 +109,6 @@ SharedMemoryHandle SharedMemory::DuplicateHandle(
return handle.Duplicate();
}
// static
int SharedMemory::GetFdFromSharedMemoryHandle(
const SharedMemoryHandle& handle) {
return handle.file_descriptor_.fd;
}
bool SharedMemory::CreateAndMapAnonymous(size_t size) {
return CreateAnonymous(size) && Map(size);
}
......@@ -135,48 +123,9 @@ bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
if (options.size > static_cast<size_t>(std::numeric_limits<int>::max()))
return false;
if (options.type == SharedMemoryHandle::MACH) {
shm_ = SharedMemoryHandle(options.size, UnguessableToken::Create());
requested_size_ = options.size;
return shm_.IsValid();
}
// This function theoretically can block on the disk. Both profiling of real
// users and local instrumentation shows that this is a real problem.
// https://code.google.com/p/chromium/issues/detail?id=466437
ThreadRestrictions::ScopedAllowIO allow_io;
ScopedFD fd;
ScopedFD readonly_fd;
FilePath path;
bool result = CreateAnonymousSharedMemory(options, &fd, &readonly_fd, &path);
if (!result)
return false;
// Should be guaranteed by CreateAnonymousSharedMemory().
DCHECK(fd.is_valid());
// Get current size.
struct stat stat;
if (fstat(fd.get(), &stat) != 0)
return false;
const size_t current_size = stat.st_size;
if (current_size != options.size) {
if (HANDLE_EINTR(ftruncate(fd.get(), options.size)) != 0)
return false;
}
shm_ = SharedMemoryHandle(options.size, UnguessableToken::Create());
requested_size_ = options.size;
int mapped_file = -1;
int readonly_mapped_file = -1;
result = PrepareMapFile(std::move(fd), std::move(readonly_fd), &mapped_file,
&readonly_mapped_file);
shm_ = SharedMemoryHandle(FileDescriptor(mapped_file, false), options.size,
UnguessableToken::Create());
readonly_shm_ =
SharedMemoryHandle(FileDescriptor(readonly_mapped_file, false),
options.size, shm_.GetGUID());
return result;
return shm_.IsValid();
}
bool SharedMemory::MapAt(off_t offset, size_t bytes) {
......@@ -192,7 +141,6 @@ bool SharedMemory::MapAt(off_t offset, size_t bytes) {
mapped_size_ = bytes;
DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) &
(SharedMemory::MAP_MINIMUM_ALIGNMENT - 1));
mapped_memory_mechanism_ = shm_.type_;
mapped_id_ = shm_.GetGUID();
SharedMemoryTracker::GetInstance()->IncrementMemoryUsage(*this);
} else {
......@@ -207,16 +155,9 @@ bool SharedMemory::Unmap() {
return false;
SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this);
switch (mapped_memory_mechanism_) {
case SharedMemoryHandle::POSIX:
munmap(memory_, mapped_size_);
break;
case SharedMemoryHandle::MACH:
mach_vm_deallocate(mach_task_self(),
reinterpret_cast<mach_vm_address_t>(memory_),
mapped_size_);
break;
}
memory_ = nullptr;
mapped_size_ = 0;
mapped_id_ = UnguessableToken();
......@@ -237,22 +178,9 @@ SharedMemoryHandle SharedMemory::TakeHandle() {
void SharedMemory::Close() {
shm_.Close();
shm_ = SharedMemoryHandle();
if (shm_.type_ == SharedMemoryHandle::POSIX) {
if (readonly_shm_.IsValid()) {
readonly_shm_.Close();
readonly_shm_ = SharedMemoryHandle();
}
}
}
SharedMemoryHandle SharedMemory::GetReadOnlyHandle() const {
if (shm_.type_ == SharedMemoryHandle::POSIX) {
// We could imagine re-opening the file from /dev/fd, but that can't make it
// readonly on Mac: https://codereview.chromium.org/27265002/#msg10.
CHECK(readonly_shm_.IsValid());
return readonly_shm_.Duplicate();
}
DCHECK(shm_.IsValid());
SharedMemoryHandle new_handle;
bool success = MakeMachSharedMemoryHandleReadOnly(&new_handle, shm_, memory_);
......
......@@ -359,6 +359,8 @@ TEST_P(SharedMemoryTest, AnonymousPrivate) {
}
}
#if !(defined(OS_MACOSX) && !defined(OS_IOS))
// The Mach functionality is tested in shared_memory_mac_unittest.cc.
TEST_P(SharedMemoryTest, GetReadOnlyHandle) {
StringPiece contents = "Hello World";
......@@ -366,10 +368,6 @@ TEST_P(SharedMemoryTest, GetReadOnlyHandle) {
SharedMemoryCreateOptions options;
options.size = contents.size();
options.share_read_only = true;
#if defined(OS_MACOSX) && !defined(OS_IOS)
// The Mach functionality is tested in shared_memory_mac_unittest.cc.
options.type = SharedMemoryHandle::POSIX;
#endif
ASSERT_TRUE(writable_shmem.Create(options));
ASSERT_TRUE(writable_shmem.Map(options.size));
memcpy(writable_shmem.memory(), contents.data(), contents.size());
......@@ -467,6 +465,7 @@ TEST_P(SharedMemoryTest, GetReadOnlyHandle) {
#error Unexpected platform; write a test that tries to make 'handle' writable.
#endif // defined(OS_POSIX) || defined(OS_WIN)
}
#endif // defined(OS_MACOSX) && !defined(OS_IOS)
TEST_P(SharedMemoryTest, ShareToSelf) {
StringPiece contents = "Hello World";
......@@ -584,7 +583,8 @@ TEST_P(SharedMemoryTest, MapTwice) {
#if defined(OS_POSIX)
// This test is not applicable for iOS (crbug.com/399384).
#if !defined(OS_IOS)
// The Mach functionality is tested in shared_memory_mac_unittest.cc.
#if !defined(OS_MACOSX) && !defined(OS_IOS)
// Create a shared memory object, mmap it, and mprotect it to PROT_EXEC.
TEST_P(SharedMemoryTest, AnonymousExecutable) {
#if defined(OS_LINUX)
......@@ -602,10 +602,6 @@ TEST_P(SharedMemoryTest, AnonymousExecutable) {
SharedMemoryCreateOptions options;
options.size = kTestSize;
options.executable = true;
#if defined(OS_MACOSX) && !defined(OS_IOS)
// The Mach functionality is tested in shared_memory_mac_unittest.cc.
options.type = SharedMemoryHandle::POSIX;
#endif
EXPECT_TRUE(shared_memory.Create(options));
EXPECT_TRUE(shared_memory.Map(shared_memory.requested_size()));
......@@ -613,7 +609,7 @@ TEST_P(SharedMemoryTest, AnonymousExecutable) {
EXPECT_EQ(0, mprotect(shared_memory.memory(), shared_memory.requested_size(),
PROT_READ | PROT_EXEC));
}
#endif // !defined(OS_IOS)
#endif // !defined(OS_MACOSX) && !defined(OS_IOS)
#if defined(OS_ANDROID)
// This test is restricted to Android since there is no way on other platforms
......@@ -658,16 +654,14 @@ class ScopedUmaskSetter {
};
// Create a shared memory object, check its permissions.
#if !(defined(OS_MACOSX) && !defined(OS_IOS))
// The Mach functionality is tested in shared_memory_mac_unittest.cc.
TEST_P(SharedMemoryTest, FilePermissionsAnonymous) {
const uint32_t kTestSize = 1 << 8;
SharedMemory shared_memory;
SharedMemoryCreateOptions options;
options.size = kTestSize;
#if defined(OS_MACOSX) && !defined(OS_IOS)
// The Mach functionality is tested in shared_memory_mac_unittest.cc.
options.type = SharedMemoryHandle::POSIX;
#endif
// Set a file mode creation mask that gives all permissions.
ScopedUmaskSetter permissive_mask(S_IWGRP | S_IWOTH);
......@@ -682,18 +676,17 @@ TEST_P(SharedMemoryTest, FilePermissionsAnonymous) {
EXPECT_FALSE(shm_stat.st_mode & S_IRWXO);
EXPECT_FALSE(shm_stat.st_mode & S_IRWXG);
}
#endif // !(defined(OS_MACOSX) && !defined(OS_IOS)
// Create a shared memory object, check its permissions.
#if !(defined(OS_MACOSX) && !defined(OS_IOS))
// The Mach functionality is tested in shared_memory_mac_unittest.cc.
TEST_P(SharedMemoryTest, FilePermissionsNamed) {
const uint32_t kTestSize = 1 << 8;
SharedMemory shared_memory;
SharedMemoryCreateOptions options;
options.size = kTestSize;
#if defined(OS_MACOSX) && !defined(OS_IOS)
// The Mach functionality is tested in shared_memory_mac_unittest.cc.
options.type = SharedMemoryHandle::POSIX;
#endif
// Set a file mode creation mask that gives all permissions.
ScopedUmaskSetter permissive_mask(S_IWGRP | S_IWOTH);
......@@ -708,6 +701,7 @@ TEST_P(SharedMemoryTest, FilePermissionsNamed) {
EXPECT_FALSE(shm_stat.st_mode & S_IRWXO);
EXPECT_FALSE(shm_stat.st_mode & S_IRWXG);
}
#endif // !(defined(OS_MACOSX) && !defined(OS_IOS)
#endif // !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
#endif // defined(OS_POSIX)
......@@ -854,15 +848,13 @@ MULTIPROCESS_TEST_MAIN(SharedMemoryTestMain) {
#endif // !defined(OS_IOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX) &&
// !defined(OS_FUCHSIA)
#if !(defined(OS_MACOSX) && !defined(OS_IOS))
// The Mach functionality is tested in shared_memory_mac_unittest.cc.
TEST_P(SharedMemoryTest, MappedId) {
const uint32_t kDataSize = 1024;
SharedMemory memory;
SharedMemoryCreateOptions options;
options.size = kDataSize;
#if defined(OS_MACOSX) && !defined(OS_IOS)
// The Mach functionality is tested in shared_memory_mac_unittest.cc.
options.type = SharedMemoryHandle::POSIX;
#endif
EXPECT_TRUE(memory.Create(options));
base::UnguessableToken id = memory.handle().GetGUID();
......@@ -878,6 +870,7 @@ TEST_P(SharedMemoryTest, MappedId) {
memory.Unmap();
EXPECT_TRUE(memory.mapped_id().is_empty());
}
#endif // !(defined(OS_MACOSX) && !defined(OS_IOS)
INSTANTIATE_TEST_CASE_P(Default,
SharedMemoryTest,
......
......@@ -41,7 +41,7 @@ static const size_t kDataSize = 1024;
// Common routine used with Posix file descriptors. Check that shared memory
// file descriptor |fd| does not allow writable mappings. Return true on
// success, false otherwise.
#if defined(OS_POSIX)
#if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS))
static bool CheckReadOnlySharedMemoryFdPosix(int fd) {
// Note that the error on Android is EPERM, unlike other platforms where
// it will be EACCES.
......@@ -66,7 +66,7 @@ static bool CheckReadOnlySharedMemoryFdPosix(int fd) {
}
return true;
}
#endif // OS_POSIX
#endif // OS_POSIX && !(defined(OS_MACOSX) && !defined(OS_IOS))
#if defined(OS_FUCHSIA)
// Fuchsia specific implementation.
......@@ -118,11 +118,7 @@ bool CheckReadOnlySharedMemoryWindowsHandle(HANDLE handle) {
bool CheckReadOnlySharedMemoryHandleForTesting(SharedMemoryHandle handle) {
#if defined(OS_MACOSX) && !defined(OS_IOS)
// For OSX, the code has to deal with both POSIX and MACH handles.
if (handle.type_ == SharedMemoryHandle::POSIX)
return CheckReadOnlySharedMemoryFdPosix(handle.file_descriptor_.fd);
else
return CheckReadOnlySharedMemoryMachPort(handle.memory_object_);
return CheckReadOnlySharedMemoryMachPort(handle.memory_object_);
#elif defined(OS_FUCHSIA)
return CheckReadOnlySharedMemoryFuchsiaHandle(
zx::unowned_vmo(handle.GetHandle()));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment