writable_shared_memory_region.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_MEMORY_WRITABLE_SHARED_MEMORY_REGION_H_
  5. #define BASE_MEMORY_WRITABLE_SHARED_MEMORY_REGION_H_
  6. #include "base/base_export.h"
  7. #include "base/check.h"
  8. #include "base/memory/platform_shared_memory_region.h"
  9. #include "base/memory/read_only_shared_memory_region.h"
  10. #include "base/memory/shared_memory_mapping.h"
  11. #include "base/memory/unsafe_shared_memory_region.h"
  12. #include "build/build_config.h"
  13. #include <stdint.h>
  14. namespace base {
  15. // Scoped move-only handle to a region of platform shared memory. The instance
  16. // owns the platform handle it wraps. Mappings created by this region are
  17. // writable. These mappings remain valid even after the region handle is moved
  18. // or destroyed.
  19. //
  20. // This region can be locked to read-only access by converting it to a
  21. // ReadOnlySharedMemoryRegion. However, unlike ReadOnlySharedMemoryRegion and
  22. // UnsafeSharedMemoryRegion, ownership of this region (while writable) is unique
  23. // and may only be transferred, not duplicated.
  24. //
  25. // Unlike ReadOnlySharedMemoryRegion and UnsafeSharedMemoryRegion,
  26. // WritableSharedMemoryRegion doesn't provide GetPlatformHandle() method to
  27. // ensure that the region is never duplicated while writable.
  28. class BASE_EXPORT WritableSharedMemoryRegion {
  29. public:
  30. using MappingType = WritableSharedMemoryMapping;
  31. // Creates a new WritableSharedMemoryRegion instance of a given
  32. // size that can be used for mapping writable shared memory into the virtual
  33. // address space.
  34. static WritableSharedMemoryRegion Create(size_t size);
  35. using CreateFunction = decltype(Create);
  36. // Returns a WritableSharedMemoryRegion built from a platform handle that was
  37. // taken from another WritableSharedMemoryRegion instance. Returns an invalid
  38. // region iff the |handle| is invalid. CHECK-fails if the |handle| isn't
  39. // writable.
  40. // This should be used only by the code passing handles across process
  41. // boundaries.
  42. static WritableSharedMemoryRegion Deserialize(
  43. subtle::PlatformSharedMemoryRegion handle);
  44. // Extracts a platform handle from the region. Ownership is transferred to the
  45. // returned region object.
  46. // This should be used only for sending the handle from the current
  47. // process to another.
  48. static subtle::PlatformSharedMemoryRegion TakeHandleForSerialization(
  49. WritableSharedMemoryRegion region);
  50. // Makes the region read-only. No new writable mappings of the region can be
  51. // created after this call. Returns an invalid region on failure.
  52. static ReadOnlySharedMemoryRegion ConvertToReadOnly(
  53. WritableSharedMemoryRegion region);
  54. // Makes the region unsafe. The region cannot be converted to read-only after
  55. // this call. Returns an invalid region on failure.
  56. static UnsafeSharedMemoryRegion ConvertToUnsafe(
  57. WritableSharedMemoryRegion region);
  58. // Default constructor initializes an invalid instance.
  59. WritableSharedMemoryRegion();
  60. // Move operations are allowed.
  61. WritableSharedMemoryRegion(WritableSharedMemoryRegion&&);
  62. WritableSharedMemoryRegion& operator=(WritableSharedMemoryRegion&&);
  63. WritableSharedMemoryRegion(const WritableSharedMemoryRegion&) = delete;
  64. WritableSharedMemoryRegion& operator=(const WritableSharedMemoryRegion&) =
  65. delete;
  66. // Destructor closes shared memory region if valid.
  67. // All created mappings will remain valid.
  68. ~WritableSharedMemoryRegion();
  69. // Maps the shared memory region into the caller's address space with write
  70. // access. The mapped address is guaranteed to have an alignment of
  71. // at least |subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment|.
  72. // Returns a valid WritableSharedMemoryMapping instance on success, invalid
  73. // otherwise. A custom |SharedMemoryMapper| for mapping (and later unmapping)
  74. // the region can be provided using the optional |mapper| parameter.
  75. WritableSharedMemoryMapping Map(SharedMemoryMapper* mapper = nullptr) const;
  76. // Similar to `Map()`, but maps only `size` bytes of the shared memory block
  77. // at byte `offset`. Returns an invalid mapping if requested bytes are out of
  78. // the region limits.
  79. //
  80. // `offset` does not need to be aligned; if `offset` is not a multiple of
  81. // `subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment`, then the
  82. // returned mapping will not respect alignment either. Internally, `offset`
  83. // and `size` are still first adjusted to respect alignment when mapping in
  84. // the shared memory region, but the returned mapping will be "unadjusted" to
  85. // match the exact `offset` and `size` requested.
  86. WritableSharedMemoryMapping MapAt(uint64_t offset,
  87. size_t size,
  88. SharedMemoryMapper* mapper = nullptr) const;
  89. // Whether underlying platform handles are valid.
  90. bool IsValid() const;
  91. // Returns the maximum mapping size that can be created from this region.
  92. size_t GetSize() const {
  93. DCHECK(IsValid());
  94. return handle_.GetSize();
  95. }
  96. // Returns 128-bit GUID of the region.
  97. const UnguessableToken& GetGUID() const {
  98. DCHECK(IsValid());
  99. return handle_.GetGUID();
  100. }
  101. #if BUILDFLAG(IS_WIN)
  102. // On Windows it is necessary in rare cases to take a writable handle from a
  103. // region that will be converted to read-only. On this platform it is a safe
  104. // operation, as the handle returned from this method will remain writable
  105. // after the region is converted to read-only. However, it breaks chromium's
  106. // WritableSharedMemoryRegion semantics and so should be use with care.
  107. HANDLE UnsafeGetPlatformHandle() const { return handle_.GetPlatformHandle(); }
  108. #endif
  109. private:
  110. friend class SharedMemoryHooks;
  111. explicit WritableSharedMemoryRegion(
  112. subtle::PlatformSharedMemoryRegion handle);
  113. static void set_create_hook(CreateFunction* hook) { create_hook_ = hook; }
  114. static CreateFunction* create_hook_;
  115. subtle::PlatformSharedMemoryRegion handle_;
  116. };
  117. } // namespace base
  118. #endif // BASE_MEMORY_WRITABLE_SHARED_MEMORY_REGION_H_