mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 22:36:09 +03:00
253 lines
10 KiB
C++
253 lines
10 KiB
C++
// 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.
|
|
|
|
#ifndef BASE_MEMORY_SHARED_MEMORY_HANDLE_H_
|
|
#define BASE_MEMORY_SHARED_MEMORY_HANDLE_H_
|
|
|
|
#include <stddef.h>
|
|
|
|
#include "base/unguessable_token.h"
|
|
#include "build/build_config.h"
|
|
|
|
#if defined(OS_WIN)
|
|
#include <windows.h>
|
|
#include "base/process/process_handle.h"
|
|
#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)
|
|
#include <sys/types.h>
|
|
#include "base/file_descriptor_posix.h"
|
|
#endif
|
|
|
|
#if defined(OS_ANDROID)
|
|
extern "C" typedef struct AHardwareBuffer AHardwareBuffer;
|
|
#endif
|
|
|
|
namespace base {
|
|
|
|
// SharedMemoryHandle is the smallest possible IPC-transportable "reference" to
|
|
// a shared memory OS resource. A "reference" can be consumed exactly once [by
|
|
// base::SharedMemory] to map the shared memory OS resource into the virtual
|
|
// address space of the current process.
|
|
// TODO(erikchen): This class should have strong ownership semantics to prevent
|
|
// leaks of the underlying OS resource. https://crbug.com/640840.
|
|
class BASE_EXPORT SharedMemoryHandle {
|
|
public:
|
|
// The default constructor returns an invalid SharedMemoryHandle.
|
|
SharedMemoryHandle();
|
|
|
|
// Standard copy constructor. The new instance shares the underlying OS
|
|
// primitives.
|
|
SharedMemoryHandle(const SharedMemoryHandle& handle);
|
|
|
|
// Standard assignment operator. The updated instance shares the underlying
|
|
// OS primitives.
|
|
SharedMemoryHandle& operator=(const SharedMemoryHandle& handle);
|
|
|
|
// Closes the underlying OS resource.
|
|
// The fact that this method needs to be "const" is an artifact of the
|
|
// original interface for base::SharedMemory::CloseHandle.
|
|
// TODO(erikchen): This doesn't clear the underlying reference, which seems
|
|
// like a bug, but is how this class has always worked. Fix this:
|
|
// https://crbug.com/716072.
|
|
void Close() const;
|
|
|
|
// Whether ownership of the underlying OS resource is implicitly passed to
|
|
// the IPC subsystem during serialization.
|
|
void SetOwnershipPassesToIPC(bool ownership_passes);
|
|
bool OwnershipPassesToIPC() const;
|
|
|
|
// Whether the underlying OS resource is valid.
|
|
bool IsValid() const;
|
|
|
|
// Duplicates the underlying OS resource. Using the return value as a
|
|
// parameter to an IPC message will cause the IPC subsystem to consume the OS
|
|
// resource.
|
|
SharedMemoryHandle Duplicate() const;
|
|
|
|
// Uniques identifies the shared memory region that the underlying OS resource
|
|
// points to. Multiple SharedMemoryHandles that point to the same shared
|
|
// memory region will have the same GUID. Preserved across IPC.
|
|
base::UnguessableToken GetGUID() const;
|
|
|
|
// Returns the size of the memory region that SharedMemoryHandle points to.
|
|
size_t GetSize() const;
|
|
|
|
#if 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
|
|
// when trying to map the SharedMemoryHandle at a later point in time.
|
|
SharedMemoryHandle(mach_vm_size_t size, const base::UnguessableToken& guid);
|
|
|
|
// Makes a Mach-based SharedMemoryHandle from |memory_object|, a named entry
|
|
// in the current task. The memory region has size |size|.
|
|
// Passing the wrong |size| has no immediate consequence, but may cause errors
|
|
// when trying to map the SharedMemoryHandle at a later point in time.
|
|
SharedMemoryHandle(mach_port_t memory_object,
|
|
mach_vm_size_t size,
|
|
const base::UnguessableToken& guid);
|
|
|
|
// Exposed so that the SharedMemoryHandle can be transported between
|
|
// processes.
|
|
mach_port_t GetMemoryObject() const;
|
|
|
|
// The SharedMemoryHandle must be valid.
|
|
// Returns whether the SharedMemoryHandle was successfully mapped into memory.
|
|
// On success, |memory| is an output variable that contains the start of the
|
|
// mapped memory.
|
|
bool MapAt(off_t offset, size_t bytes, void** memory, bool read_only);
|
|
#elif defined(OS_FUCHSIA)
|
|
// Takes implicit ownership of |h|.
|
|
// |guid| uniquely identifies the shared memory region pointed to by the
|
|
// underlying OS resource. If the zx_handle_t is associated with another
|
|
// SharedMemoryHandle, the caller must pass the |guid| of that
|
|
// SharedMemoryHandle. Otherwise, the caller should generate a new
|
|
// UnguessableToken.
|
|
// Passing the wrong |size| has no immediate consequence, but may cause errors
|
|
// when trying to map the SharedMemoryHandle at a later point in time.
|
|
SharedMemoryHandle(zx_handle_t h,
|
|
size_t size,
|
|
const base::UnguessableToken& guid);
|
|
zx_handle_t GetHandle() const;
|
|
#elif defined(OS_WIN)
|
|
// Takes implicit ownership of |h|.
|
|
// |guid| uniquely identifies the shared memory region pointed to by the
|
|
// underlying OS resource. If the HANDLE is associated with another
|
|
// SharedMemoryHandle, the caller must pass the |guid| of that
|
|
// SharedMemoryHandle. Otherwise, the caller should generate a new
|
|
// UnguessableToken.
|
|
// Passing the wrong |size| has no immediate consequence, but may cause errors
|
|
// when trying to map the SharedMemoryHandle at a later point in time.
|
|
SharedMemoryHandle(HANDLE h, size_t size, const base::UnguessableToken& guid);
|
|
HANDLE GetHandle() const;
|
|
#else
|
|
// Creates a SharedMemoryHandle from an |fd| supplied from an external
|
|
// service.
|
|
// Passing the wrong |size| has no immediate consequence, but may cause errors
|
|
// when trying to map the SharedMemoryHandle at a later point in time.
|
|
static SharedMemoryHandle ImportHandle(int fd, size_t size);
|
|
|
|
// Returns the underlying OS resource.
|
|
int GetHandle() const;
|
|
|
|
// Invalidates [but doesn't close] the underlying OS resource. This will leak
|
|
// unless the caller is careful.
|
|
int Release();
|
|
#endif
|
|
|
|
#if defined(OS_ANDROID)
|
|
enum class Type {
|
|
// The SharedMemoryHandle is not backed by a handle. This is used for
|
|
// a default-constructed SharedMemoryHandle() or for a failed duplicate.
|
|
// The other types are assumed to be valid.
|
|
INVALID,
|
|
// The SharedMemoryHandle is backed by a valid fd for ashmem.
|
|
ASHMEM,
|
|
// The SharedMemoryHandle is backed by a valid AHardwareBuffer object.
|
|
ANDROID_HARDWARE_BUFFER,
|
|
|
|
LAST = ANDROID_HARDWARE_BUFFER
|
|
};
|
|
Type GetType() const { return type_; }
|
|
SharedMemoryHandle(AHardwareBuffer* buffer,
|
|
size_t size,
|
|
const base::UnguessableToken& guid);
|
|
// Constructs a handle from file descriptor and type. Both ASHMEM and
|
|
// AHardwareBuffer types are transported via file descriptor for IPC, so the
|
|
// type field is needed to distinguish them. The generic file descriptor
|
|
// constructor below assumes type ASHMEM.
|
|
SharedMemoryHandle(Type type,
|
|
const base::FileDescriptor& file_descriptor,
|
|
size_t size,
|
|
const base::UnguessableToken& guid);
|
|
AHardwareBuffer* GetMemoryObject() const;
|
|
#endif
|
|
|
|
#if defined(OS_POSIX) && !defined(OS_FUCHSIA)
|
|
// 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
|
|
// |fd| if |auto_close| is true. Unfortunately, it's common for existing code
|
|
// to make shallow copies of SharedMemoryHandle, and the one that is finally
|
|
// passed into a base::SharedMemory is the one that "consumes" the fd.
|
|
//
|
|
// |guid| uniquely identifies the shared memory region pointed to by the
|
|
// underlying OS resource. If |file_descriptor| is associated with another
|
|
// SharedMemoryHandle, the caller must pass the |guid| of that
|
|
// SharedMemoryHandle. Otherwise, the caller should generate a new
|
|
// UnguessableToken.
|
|
// Passing the wrong |size| has no immediate consequence, but may cause errors
|
|
// when trying to map the SharedMemoryHandle at a later point in time.
|
|
SharedMemoryHandle(const base::FileDescriptor& file_descriptor,
|
|
size_t size,
|
|
const base::UnguessableToken& guid);
|
|
#endif
|
|
|
|
private:
|
|
#if defined(OS_MACOSX) && !defined(OS_IOS)
|
|
friend class SharedMemory;
|
|
|
|
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_;
|
|
|
|
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;
|
|
};
|
|
};
|
|
#elif defined(OS_ANDROID)
|
|
// Each instance of a SharedMemoryHandle is either INVALID, or backed by an
|
|
// ashmem fd, or backed by an AHardwareBuffer. |type_| determines the backing
|
|
// member.
|
|
Type type_ = Type::INVALID;
|
|
FileDescriptor file_descriptor_;
|
|
AHardwareBuffer* memory_object_ = nullptr;
|
|
bool ownership_passes_to_ipc_ = false;
|
|
#elif defined(OS_FUCHSIA)
|
|
zx_handle_t handle_ = ZX_HANDLE_INVALID;
|
|
bool ownership_passes_to_ipc_ = false;
|
|
#elif defined(OS_WIN)
|
|
HANDLE handle_ = nullptr;
|
|
|
|
// Whether passing this object as a parameter to an IPC message passes
|
|
// ownership of |handle_| to the IPC stack. This is meant to mimic the
|
|
// behavior of the |auto_close| parameter of FileDescriptor. This member only
|
|
// affects attachment-brokered SharedMemoryHandles.
|
|
// Defaults to |false|.
|
|
bool ownership_passes_to_ipc_ = false;
|
|
#else
|
|
FileDescriptor file_descriptor_;
|
|
#endif
|
|
|
|
base::UnguessableToken guid_;
|
|
|
|
// The size of the region referenced by the SharedMemoryHandle.
|
|
size_t size_ = 0;
|
|
};
|
|
|
|
} // namespace base
|
|
|
|
#endif // BASE_MEMORY_SHARED_MEMORY_HANDLE_H_
|