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 5 #ifndef BASE_MEMORY_READ_ONLY_SHARED_MEMORY_REGION_H_ 6 #define BASE_MEMORY_READ_ONLY_SHARED_MEMORY_REGION_H_ 7 8 #include <utility> 9 10 #include "base/macros.h" 11 #include "base/memory/platform_shared_memory_region.h" 12 #include "base/memory/shared_memory_mapping.h" 13 14 namespace base { 15 16 struct MappedReadOnlyRegion; 17 18 // Scoped move-only handle to a region of platform shared memory. The instance 19 // owns the platform handle it wraps. Mappings created by this region are 20 // read-only. These mappings remain valid even after the region handle is moved 21 // or destroyed. 22 class BASE_EXPORT ReadOnlySharedMemoryRegion { 23 public: 24 using MappingType = ReadOnlySharedMemoryMapping; 25 // Creates a new ReadOnlySharedMemoryRegion instance of a given size along 26 // with the WritableSharedMemoryMapping which provides the only way to modify 27 // the content of the newly created region. The returned region and mapping 28 // are guaranteed to either be both valid or both invalid. Use 29 // |MappedReadOnlyRegion::IsValid()| as a shortcut for checking creation 30 // success. 31 // 32 // This means that the caller's process is the only process that can modify 33 // the region content. If you need to pass write access to another process, 34 // consider using WritableSharedMemoryRegion or UnsafeSharedMemoryRegion. 35 static MappedReadOnlyRegion Create(size_t size); 36 37 // Returns a ReadOnlySharedMemoryRegion built from a platform-specific handle 38 // that was taken from another ReadOnlySharedMemoryRegion instance. Returns an 39 // invalid region iff the |handle| is invalid. CHECK-fails if the |handle| 40 // isn't read-only. 41 // This should be used only by the code passing handles across process 42 // boundaries. 43 static ReadOnlySharedMemoryRegion Deserialize( 44 subtle::PlatformSharedMemoryRegion handle); 45 46 // Extracts a platform handle from the region. Ownership is transferred to the 47 // returned region object. 48 // This should be used only for sending the handle from the current process to 49 // another. 50 static subtle::PlatformSharedMemoryRegion TakeHandleForSerialization( 51 ReadOnlySharedMemoryRegion region); 52 53 // Default constructor initializes an invalid instance. 54 ReadOnlySharedMemoryRegion(); 55 56 // Move operations are allowed. 57 ReadOnlySharedMemoryRegion(ReadOnlySharedMemoryRegion&&); 58 ReadOnlySharedMemoryRegion& operator=(ReadOnlySharedMemoryRegion&&); 59 60 // Destructor closes shared memory region if valid. 61 // All created mappings will remain valid. 62 ~ReadOnlySharedMemoryRegion(); 63 64 // Duplicates the underlying platform handle and creates a new 65 // ReadOnlySharedMemoryRegion instance that owns this handle. Returns a valid 66 // ReadOnlySharedMemoryRegion on success, invalid otherwise. The current 67 // region instance remains valid in any case. 68 ReadOnlySharedMemoryRegion Duplicate() const; 69 70 // Maps the shared memory region into the caller's address space with 71 // read-only access. The mapped address is guaranteed to have an alignment of 72 // at least |subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment|. 73 // Returns a valid ReadOnlySharedMemoryMapping instance on success, invalid 74 // otherwise. 75 ReadOnlySharedMemoryMapping Map() const; 76 77 // Same as above, but maps only |size| bytes of the shared memory region 78 // starting with the given |offset|. |offset| must be aligned to value of 79 // |SysInfo::VMAllocationGranularity()|. Returns an invalid mapping if 80 // requested bytes are out of the region limits. 81 ReadOnlySharedMemoryMapping MapAt(off_t offset, size_t size) const; 82 83 // Whether the underlying platform handle is valid. 84 bool IsValid() const; 85 86 // Returns the maximum mapping size that can be created from this region. GetSize()87 size_t GetSize() const { 88 DCHECK(IsValid()); 89 return handle_.GetSize(); 90 } 91 92 // Returns 128-bit GUID of the region. GetGUID()93 const UnguessableToken& GetGUID() const { 94 DCHECK(IsValid()); 95 return handle_.GetGUID(); 96 } 97 98 private: 99 explicit ReadOnlySharedMemoryRegion( 100 subtle::PlatformSharedMemoryRegion handle); 101 102 subtle::PlatformSharedMemoryRegion handle_; 103 104 DISALLOW_COPY_AND_ASSIGN(ReadOnlySharedMemoryRegion); 105 }; 106 107 // Helper struct for return value of ReadOnlySharedMemoryRegion::Create(). 108 struct MappedReadOnlyRegion { 109 ReadOnlySharedMemoryRegion region; 110 WritableSharedMemoryMapping mapping; 111 // Helper function to check return value of 112 // ReadOnlySharedMemoryRegion::Create(). |region| and |mapping| either both 113 // valid or invalid. IsValidMappedReadOnlyRegion114 bool IsValid() { 115 DCHECK_EQ(region.IsValid(), mapping.IsValid()); 116 return region.IsValid() && mapping.IsValid(); 117 } 118 }; 119 120 } // namespace base 121 122 #endif // BASE_MEMORY_READ_ONLY_SHARED_MEMORY_REGION_H_ 123