1 // Copyright 2018 The Chromium Authors
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 "build/build_config.h"
10
11 namespace base {
12
13 ReadOnlySharedMemoryRegion::CreateFunction*
14 ReadOnlySharedMemoryRegion::create_hook_ = nullptr;
15
16 // static
Create(size_t size,SharedMemoryMapper * mapper)17 MappedReadOnlyRegion ReadOnlySharedMemoryRegion::Create(
18 size_t size,
19 SharedMemoryMapper* mapper) {
20 if (create_hook_)
21 return create_hook_(size, mapper);
22
23 subtle::PlatformSharedMemoryRegion handle =
24 subtle::PlatformSharedMemoryRegion::CreateWritable(size);
25 if (!handle.IsValid())
26 return {};
27
28 auto result = handle.MapAt(0, handle.GetSize(), mapper);
29 if (!result.has_value())
30 return {};
31
32 WritableSharedMemoryMapping mapping(result.value(), size, handle.GetGUID(),
33 mapper);
34 #if BUILDFLAG(IS_MAC)
35 handle.ConvertToReadOnly(mapping.memory());
36 #else
37 handle.ConvertToReadOnly();
38 #endif // BUILDFLAG(IS_MAC)
39 ReadOnlySharedMemoryRegion region(std::move(handle));
40
41 if (!region.IsValid() || !mapping.IsValid())
42 return {};
43
44 return {std::move(region), std::move(mapping)};
45 }
46
47 // static
Deserialize(subtle::PlatformSharedMemoryRegion handle)48 ReadOnlySharedMemoryRegion ReadOnlySharedMemoryRegion::Deserialize(
49 subtle::PlatformSharedMemoryRegion handle) {
50 return ReadOnlySharedMemoryRegion(std::move(handle));
51 }
52
53 // static
54 subtle::PlatformSharedMemoryRegion
TakeHandleForSerialization(ReadOnlySharedMemoryRegion region)55 ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
56 ReadOnlySharedMemoryRegion region) {
57 return std::move(region.handle_);
58 }
59
60 ReadOnlySharedMemoryRegion::ReadOnlySharedMemoryRegion() = default;
61 ReadOnlySharedMemoryRegion::ReadOnlySharedMemoryRegion(
62 ReadOnlySharedMemoryRegion&& region) = default;
63 ReadOnlySharedMemoryRegion& ReadOnlySharedMemoryRegion::operator=(
64 ReadOnlySharedMemoryRegion&& region) = default;
65 ReadOnlySharedMemoryRegion::~ReadOnlySharedMemoryRegion() = default;
66
Duplicate() const67 ReadOnlySharedMemoryRegion ReadOnlySharedMemoryRegion::Duplicate() const {
68 return ReadOnlySharedMemoryRegion(handle_.Duplicate());
69 }
70
Map(SharedMemoryMapper * mapper) const71 ReadOnlySharedMemoryMapping ReadOnlySharedMemoryRegion::Map(
72 SharedMemoryMapper* mapper) const {
73 return MapAt(0, handle_.GetSize(), mapper);
74 }
75
MapAt(uint64_t offset,size_t size,SharedMemoryMapper * mapper) const76 ReadOnlySharedMemoryMapping ReadOnlySharedMemoryRegion::MapAt(
77 uint64_t offset,
78 size_t size,
79 SharedMemoryMapper* mapper) const {
80 if (!IsValid())
81 return {};
82
83 auto result = handle_.MapAt(offset, size, mapper);
84 if (!result.has_value())
85 return {};
86
87 return ReadOnlySharedMemoryMapping(result.value(), size, handle_.GetGUID(),
88 mapper);
89 }
90
IsValid() const91 bool ReadOnlySharedMemoryRegion::IsValid() const {
92 return handle_.IsValid();
93 }
94
ReadOnlySharedMemoryRegion(subtle::PlatformSharedMemoryRegion handle)95 ReadOnlySharedMemoryRegion::ReadOnlySharedMemoryRegion(
96 subtle::PlatformSharedMemoryRegion handle)
97 : handle_(std::move(handle)) {
98 if (handle_.IsValid()) {
99 CHECK_EQ(handle_.GetMode(),
100 subtle::PlatformSharedMemoryRegion::Mode::kReadOnly);
101 }
102 }
103
104 } // namespace base
105