Home | History | Annotate | Download | only in memory
      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.
     87   size_t GetSize() const {
     88     DCHECK(IsValid());
     89     return handle_.GetSize();
     90   }
     91 
     92   // Returns 128-bit GUID of the region.
     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.
    114   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