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 #include "base/memory/read_only_shared_memory_region.h"
6 
7 #include <utility>
8 
9 #include "base/memory/shared_memory.h"
10 #include "build/build_config.h"
11 
12 namespace base {
13 
14 // static
Create(size_t size)15 MappedReadOnlyRegion ReadOnlySharedMemoryRegion::Create(size_t size) {
16   subtle::PlatformSharedMemoryRegion handle =
17       subtle::PlatformSharedMemoryRegion::CreateWritable(size);
18   if (!handle.IsValid())
19     return {};
20 
21   void* memory_ptr = nullptr;
22   size_t mapped_size = 0;
23   if (!handle.MapAt(0, handle.GetSize(), &memory_ptr, &mapped_size))
24     return {};
25 
26   WritableSharedMemoryMapping mapping(memory_ptr, size, mapped_size,
27                                       handle.GetGUID());
28 #if defined(OS_MACOSX) && !defined(OS_IOS)
29   handle.ConvertToReadOnly(memory_ptr);
30 #else
31   handle.ConvertToReadOnly();
32 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
33   ReadOnlySharedMemoryRegion region(std::move(handle));
34 
35   if (!region.IsValid() || !mapping.IsValid())
36     return {};
37 
38   return {std::move(region), std::move(mapping)};
39 }
40 
41 // static
Deserialize(subtle::PlatformSharedMemoryRegion handle)42 ReadOnlySharedMemoryRegion ReadOnlySharedMemoryRegion::Deserialize(
43     subtle::PlatformSharedMemoryRegion handle) {
44   return ReadOnlySharedMemoryRegion(std::move(handle));
45 }
46 
47 // static
48 subtle::PlatformSharedMemoryRegion
TakeHandleForSerialization(ReadOnlySharedMemoryRegion region)49 ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
50     ReadOnlySharedMemoryRegion region) {
51   return std::move(region.handle_);
52 }
53 
54 ReadOnlySharedMemoryRegion::ReadOnlySharedMemoryRegion() = default;
55 ReadOnlySharedMemoryRegion::ReadOnlySharedMemoryRegion(
56     ReadOnlySharedMemoryRegion&& region) = default;
57 ReadOnlySharedMemoryRegion& ReadOnlySharedMemoryRegion::operator=(
58     ReadOnlySharedMemoryRegion&& region) = default;
59 ReadOnlySharedMemoryRegion::~ReadOnlySharedMemoryRegion() = default;
60 
Duplicate() const61 ReadOnlySharedMemoryRegion ReadOnlySharedMemoryRegion::Duplicate() const {
62   return ReadOnlySharedMemoryRegion(handle_.Duplicate());
63 }
64 
Map() const65 ReadOnlySharedMemoryMapping ReadOnlySharedMemoryRegion::Map() const {
66   return MapAt(0, handle_.GetSize());
67 }
68 
MapAt(off_t offset,size_t size) const69 ReadOnlySharedMemoryMapping ReadOnlySharedMemoryRegion::MapAt(
70     off_t offset,
71     size_t size) const {
72   if (!IsValid())
73     return {};
74 
75   void* memory = nullptr;
76   size_t mapped_size = 0;
77   if (!handle_.MapAt(offset, size, &memory, &mapped_size))
78     return {};
79 
80   return ReadOnlySharedMemoryMapping(memory, size, mapped_size,
81                                      handle_.GetGUID());
82 }
83 
IsValid() const84 bool ReadOnlySharedMemoryRegion::IsValid() const {
85   return handle_.IsValid();
86 }
87 
ReadOnlySharedMemoryRegion(subtle::PlatformSharedMemoryRegion handle)88 ReadOnlySharedMemoryRegion::ReadOnlySharedMemoryRegion(
89     subtle::PlatformSharedMemoryRegion handle)
90     : handle_(std::move(handle)) {
91   if (handle_.IsValid()) {
92     CHECK_EQ(handle_.GetMode(),
93              subtle::PlatformSharedMemoryRegion::Mode::kReadOnly);
94   }
95 }
96 
97 }  // namespace base
98