• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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