123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- // Copyright 2018 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_WRITABLE_SHARED_MEMORY_REGION_H_
- #define BASE_MEMORY_WRITABLE_SHARED_MEMORY_REGION_H_
- #include "base/base_export.h"
- #include "base/check.h"
- #include "base/memory/platform_shared_memory_region.h"
- #include "base/memory/read_only_shared_memory_region.h"
- #include "base/memory/shared_memory_mapping.h"
- #include "base/memory/unsafe_shared_memory_region.h"
- #include "build/build_config.h"
- #include <stdint.h>
- namespace base {
- // Scoped move-only handle to a region of platform shared memory. The instance
- // owns the platform handle it wraps. Mappings created by this region are
- // writable. These mappings remain valid even after the region handle is moved
- // or destroyed.
- //
- // This region can be locked to read-only access by converting it to a
- // ReadOnlySharedMemoryRegion. However, unlike ReadOnlySharedMemoryRegion and
- // UnsafeSharedMemoryRegion, ownership of this region (while writable) is unique
- // and may only be transferred, not duplicated.
- //
- // Unlike ReadOnlySharedMemoryRegion and UnsafeSharedMemoryRegion,
- // WritableSharedMemoryRegion doesn't provide GetPlatformHandle() method to
- // ensure that the region is never duplicated while writable.
- class BASE_EXPORT WritableSharedMemoryRegion {
- public:
- using MappingType = WritableSharedMemoryMapping;
- // Creates a new WritableSharedMemoryRegion instance of a given
- // size that can be used for mapping writable shared memory into the virtual
- // address space.
- static WritableSharedMemoryRegion Create(size_t size);
- using CreateFunction = decltype(Create);
- // Returns a WritableSharedMemoryRegion built from a platform handle that was
- // taken from another WritableSharedMemoryRegion instance. Returns an invalid
- // region iff the |handle| is invalid. CHECK-fails if the |handle| isn't
- // writable.
- // This should be used only by the code passing handles across process
- // boundaries.
- static WritableSharedMemoryRegion Deserialize(
- subtle::PlatformSharedMemoryRegion handle);
- // Extracts a platform handle from the region. Ownership is transferred to the
- // returned region object.
- // This should be used only for sending the handle from the current
- // process to another.
- static subtle::PlatformSharedMemoryRegion TakeHandleForSerialization(
- WritableSharedMemoryRegion region);
- // Makes the region read-only. No new writable mappings of the region can be
- // created after this call. Returns an invalid region on failure.
- static ReadOnlySharedMemoryRegion ConvertToReadOnly(
- WritableSharedMemoryRegion region);
- // Makes the region unsafe. The region cannot be converted to read-only after
- // this call. Returns an invalid region on failure.
- static UnsafeSharedMemoryRegion ConvertToUnsafe(
- WritableSharedMemoryRegion region);
- // Default constructor initializes an invalid instance.
- WritableSharedMemoryRegion();
- // Move operations are allowed.
- WritableSharedMemoryRegion(WritableSharedMemoryRegion&&);
- WritableSharedMemoryRegion& operator=(WritableSharedMemoryRegion&&);
- WritableSharedMemoryRegion(const WritableSharedMemoryRegion&) = delete;
- WritableSharedMemoryRegion& operator=(const WritableSharedMemoryRegion&) =
- delete;
- // Destructor closes shared memory region if valid.
- // All created mappings will remain valid.
- ~WritableSharedMemoryRegion();
- // Maps the shared memory region into the caller's address space with write
- // access. The mapped address is guaranteed to have an alignment of
- // at least |subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment|.
- // Returns a valid WritableSharedMemoryMapping instance on success, invalid
- // otherwise. A custom |SharedMemoryMapper| for mapping (and later unmapping)
- // the region can be provided using the optional |mapper| parameter.
- WritableSharedMemoryMapping Map(SharedMemoryMapper* mapper = nullptr) const;
- // Similar to `Map()`, but maps only `size` bytes of the shared memory block
- // at byte `offset`. Returns an invalid mapping if requested bytes are out of
- // the region limits.
- //
- // `offset` does not need to be aligned; if `offset` is not a multiple of
- // `subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment`, then the
- // returned mapping will not respect alignment either. Internally, `offset`
- // and `size` are still first adjusted to respect alignment when mapping in
- // the shared memory region, but the returned mapping will be "unadjusted" to
- // match the exact `offset` and `size` requested.
- WritableSharedMemoryMapping MapAt(uint64_t offset,
- size_t size,
- SharedMemoryMapper* mapper = nullptr) const;
- // Whether underlying platform handles are valid.
- bool IsValid() const;
- // Returns the maximum mapping size that can be created from this region.
- size_t GetSize() const {
- DCHECK(IsValid());
- return handle_.GetSize();
- }
- // Returns 128-bit GUID of the region.
- const UnguessableToken& GetGUID() const {
- DCHECK(IsValid());
- return handle_.GetGUID();
- }
- #if BUILDFLAG(IS_WIN)
- // On Windows it is necessary in rare cases to take a writable handle from a
- // region that will be converted to read-only. On this platform it is a safe
- // operation, as the handle returned from this method will remain writable
- // after the region is converted to read-only. However, it breaks chromium's
- // WritableSharedMemoryRegion semantics and so should be use with care.
- HANDLE UnsafeGetPlatformHandle() const { return handle_.GetPlatformHandle(); }
- #endif
- private:
- friend class SharedMemoryHooks;
- explicit WritableSharedMemoryRegion(
- subtle::PlatformSharedMemoryRegion handle);
- static void set_create_hook(CreateFunction* hook) { create_hook_ = hook; }
- static CreateFunction* create_hook_;
- subtle::PlatformSharedMemoryRegion handle_;
- };
- } // namespace base
- #endif // BASE_MEMORY_WRITABLE_SHARED_MEMORY_REGION_H_
|