Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(351)

Side by Side Diff: base/memory/shared_memory_handle_mac.cc

Issue 1897623002: Remove POSIX shared memory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments from amistry. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/memory/shared_memory_handle.h ('k') | base/memory/shared_memory_mac.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/memory/shared_memory_handle.h" 5 #include "base/memory/shared_memory_handle.h"
6 6
7 #include <mach/mach_vm.h> 7 #include <mach/mach_vm.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <sys/mman.h> 9 #include <sys/mman.h>
10 #include <unistd.h> 10 #include <unistd.h>
11 11
12 #include "base/mac/mac_util.h" 12 #include "base/mac/mac_util.h"
13 #include "base/posix/eintr_wrapper.h" 13 #include "base/posix/eintr_wrapper.h"
14 14
15 namespace base { 15 namespace base {
16 16
17 static_assert(sizeof(SharedMemoryHandle::Type) <= 17 SharedMemoryHandle::SharedMemoryHandle() {}
18 sizeof(SharedMemoryHandle::TypeWireFormat),
19 "Size of enum SharedMemoryHandle::Type exceeds size of type "
20 "transmitted over wire.");
21
22 SharedMemoryHandle::SharedMemoryHandle() : type_(POSIX), file_descriptor_() {}
23
24 SharedMemoryHandle::SharedMemoryHandle(
25 const base::FileDescriptor& file_descriptor)
26 : type_(POSIX), file_descriptor_(file_descriptor) {}
27
28 SharedMemoryHandle::SharedMemoryHandle(int fd, bool auto_close)
29 : type_(POSIX), file_descriptor_(fd, auto_close) {}
30 18
31 SharedMemoryHandle::SharedMemoryHandle(mach_vm_size_t size) { 19 SharedMemoryHandle::SharedMemoryHandle(mach_vm_size_t size) {
32 type_ = MACH;
33 mach_port_t named_right; 20 mach_port_t named_right;
34 kern_return_t kr = mach_make_memory_entry_64( 21 kern_return_t kr = mach_make_memory_entry_64(
35 mach_task_self(), 22 mach_task_self(),
36 &size, 23 &size,
37 0, // Address. 24 0, // Address.
38 MAP_MEM_NAMED_CREATE | VM_PROT_READ | VM_PROT_WRITE, 25 MAP_MEM_NAMED_CREATE | VM_PROT_READ | VM_PROT_WRITE,
39 &named_right, 26 &named_right,
40 MACH_PORT_NULL); // Parent handle. 27 MACH_PORT_NULL); // Parent handle.
41 if (kr != KERN_SUCCESS) { 28 if (kr != KERN_SUCCESS) {
42 memory_object_ = MACH_PORT_NULL; 29 memory_object_ = MACH_PORT_NULL;
43 return; 30 return;
44 } 31 }
45 32
46 memory_object_ = named_right; 33 memory_object_ = named_right;
47 size_ = size; 34 size_ = size;
48 pid_ = GetCurrentProcId(); 35 pid_ = GetCurrentProcId();
49 ownership_passes_to_ipc_ = false; 36 ownership_passes_to_ipc_ = false;
50 } 37 }
51 38
52 SharedMemoryHandle::SharedMemoryHandle(mach_port_t memory_object, 39 SharedMemoryHandle::SharedMemoryHandle(mach_port_t memory_object,
53 mach_vm_size_t size, 40 mach_vm_size_t size,
54 base::ProcessId pid) 41 base::ProcessId pid)
55 : type_(MACH), 42 : memory_object_(memory_object),
56 memory_object_(memory_object),
57 size_(size), 43 size_(size),
58 pid_(pid), 44 pid_(pid),
59 ownership_passes_to_ipc_(false) {} 45 ownership_passes_to_ipc_(false) {}
60 46
61 SharedMemoryHandle::SharedMemoryHandle(const SharedMemoryHandle& handle) 47 SharedMemoryHandle::SharedMemoryHandle(const SharedMemoryHandle& handle) {
62 : type_(handle.type_) {
63 CopyRelevantData(handle); 48 CopyRelevantData(handle);
64 } 49 }
65 50
66 SharedMemoryHandle& SharedMemoryHandle::operator=( 51 SharedMemoryHandle& SharedMemoryHandle::operator=(
67 const SharedMemoryHandle& handle) { 52 const SharedMemoryHandle& handle) {
68 if (this == &handle) 53 if (this == &handle)
69 return *this; 54 return *this;
70 55
71 type_ = handle.type_;
72 CopyRelevantData(handle); 56 CopyRelevantData(handle);
73 return *this; 57 return *this;
74 } 58 }
75 59
76 SharedMemoryHandle SharedMemoryHandle::Duplicate() const { 60 SharedMemoryHandle SharedMemoryHandle::Duplicate() const {
77 switch (type_) { 61 if (!IsValid())
78 case POSIX: { 62 return SharedMemoryHandle(MACH_PORT_NULL, 0, 0);
79 if (!IsValid())
80 return SharedMemoryHandle();
81 63
82 int duped_fd = HANDLE_EINTR(dup(file_descriptor_.fd)); 64 // Increment the ref count.
83 if (duped_fd < 0) 65 kern_return_t kr = mach_port_mod_refs(mach_task_self(), memory_object_,
84 return SharedMemoryHandle(); 66 MACH_PORT_RIGHT_SEND, 1);
85 return SharedMemoryHandle(duped_fd, true); 67 DCHECK_EQ(kr, KERN_SUCCESS);
86 } 68 SharedMemoryHandle handle(*this);
87 case MACH: { 69 handle.SetOwnershipPassesToIPC(true);
88 if (!IsValid()) 70 return handle;
89 return SharedMemoryHandle(MACH_PORT_NULL, 0, 0);
90
91 // Increment the ref count.
92 kern_return_t kr = mach_port_mod_refs(mach_task_self(), memory_object_,
93 MACH_PORT_RIGHT_SEND, 1);
94 DCHECK_EQ(kr, KERN_SUCCESS);
95 SharedMemoryHandle handle(*this);
96 handle.SetOwnershipPassesToIPC(true);
97 return handle;
98 }
99 }
100 } 71 }
101 72
102 bool SharedMemoryHandle::operator==(const SharedMemoryHandle& handle) const { 73 bool SharedMemoryHandle::operator==(const SharedMemoryHandle& handle) const {
103 if (!IsValid() && !handle.IsValid()) 74 if (!IsValid() && !handle.IsValid())
104 return true; 75 return true;
105 76
106 if (type_ != handle.type_) 77 return memory_object_ == handle.memory_object_ && size_ == handle.size_ &&
107 return false; 78 pid_ == handle.pid_;
108
109 switch (type_) {
110 case POSIX:
111 return file_descriptor_ == handle.file_descriptor_;
112 case MACH:
113 return memory_object_ == handle.memory_object_ && size_ == handle.size_ &&
114 pid_ == handle.pid_;
115 }
116 } 79 }
117 80
118 bool SharedMemoryHandle::operator!=(const SharedMemoryHandle& handle) const { 81 bool SharedMemoryHandle::operator!=(const SharedMemoryHandle& handle) const {
119 return !(*this == handle); 82 return !(*this == handle);
120 } 83 }
121 84
122 SharedMemoryHandle::Type SharedMemoryHandle::GetType() const {
123 return type_;
124 }
125
126 bool SharedMemoryHandle::IsValid() const { 85 bool SharedMemoryHandle::IsValid() const {
127 switch (type_) { 86 return memory_object_ != MACH_PORT_NULL;
128 case POSIX:
129 return file_descriptor_.fd >= 0;
130 case MACH:
131 return memory_object_ != MACH_PORT_NULL;
132 }
133 }
134
135 void SharedMemoryHandle::SetFileHandle(int fd, bool auto_close) {
136 DCHECK(!IsValid());
137 file_descriptor_.fd = fd;
138 file_descriptor_.auto_close = auto_close;
139 type_ = POSIX;
140 }
141
142 const FileDescriptor SharedMemoryHandle::GetFileDescriptor() const {
143 DCHECK_EQ(type_, POSIX);
144 return file_descriptor_;
145 } 87 }
146 88
147 mach_port_t SharedMemoryHandle::GetMemoryObject() const { 89 mach_port_t SharedMemoryHandle::GetMemoryObject() const {
148 DCHECK_EQ(type_, MACH);
149 return memory_object_; 90 return memory_object_;
150 } 91 }
151 92
152 bool SharedMemoryHandle::GetSize(size_t* size) const { 93 bool SharedMemoryHandle::GetSize(size_t* size) const {
153 if (!IsValid()) 94 if (!IsValid()) {
154 return false; 95 *size = 0;
96 return true;
97 }
155 98
156 switch (type_) { 99 *size = size_;
157 case SharedMemoryHandle::POSIX: 100 return true;
158 struct stat st;
159 if (fstat(file_descriptor_.fd, &st) != 0)
160 return false;
161 if (st.st_size < 0)
162 return false;
163 *size = st.st_size;
164 return true;
165 case SharedMemoryHandle::MACH:
166 *size = size_;
167 return true;
168 }
169 } 101 }
170 102
171 bool SharedMemoryHandle::MapAt(off_t offset, 103 bool SharedMemoryHandle::MapAt(off_t offset,
172 size_t bytes, 104 size_t bytes,
173 void** memory, 105 void** memory,
174 bool read_only) { 106 bool read_only) {
175 DCHECK(IsValid()); 107 DCHECK(IsValid());
176 switch (type_) { 108 DCHECK_EQ(pid_, GetCurrentProcId());
177 case SharedMemoryHandle::POSIX: 109 kern_return_t kr = mach_vm_map(
178 *memory = mmap(nullptr, bytes, PROT_READ | (read_only ? 0 : PROT_WRITE), 110 mach_task_self(),
179 MAP_SHARED, file_descriptor_.fd, offset); 111 reinterpret_cast<mach_vm_address_t*>(memory), // Output parameter
180 112 bytes,
181 return *memory && *memory != reinterpret_cast<void*>(-1); 113 0, // Alignment mask
182 case SharedMemoryHandle::MACH: 114 VM_FLAGS_ANYWHERE, memory_object_, offset,
183 // The flag VM_PROT_IS_MASK is only supported on OSX 10.7+. 115 FALSE, // Copy
184 DCHECK(mac::IsOSLionOrLater()); 116 VM_PROT_READ | (read_only ? 0 : VM_PROT_WRITE), // Current protection
185 117 VM_PROT_WRITE | VM_PROT_READ | VM_PROT_IS_MASK, // Maximum protection
186 DCHECK_EQ(pid_, GetCurrentProcId()); 118 VM_INHERIT_NONE);
187 kern_return_t kr = mach_vm_map( 119 return kr == KERN_SUCCESS;
188 mach_task_self(),
189 reinterpret_cast<mach_vm_address_t*>(memory), // Output parameter
190 bytes,
191 0, // Alignment mask
192 VM_FLAGS_ANYWHERE,
193 memory_object_,
194 offset,
195 FALSE, // Copy
196 VM_PROT_READ | (read_only ? 0 : VM_PROT_WRITE), // Current protection
197 VM_PROT_WRITE | VM_PROT_READ | VM_PROT_IS_MASK, // Maximum protection
198 VM_INHERIT_NONE);
199 return kr == KERN_SUCCESS;
200 }
201 } 120 }
202 121
203 void SharedMemoryHandle::Close() const { 122 void SharedMemoryHandle::Close() const {
204 if (!IsValid()) 123 if (!IsValid())
205 return; 124 return;
206 125
207 switch (type_) { 126 kern_return_t kr = mach_port_deallocate(mach_task_self(), memory_object_);
208 case POSIX: 127 if (kr != KERN_SUCCESS)
209 if (IGNORE_EINTR(close(file_descriptor_.fd)) < 0) 128 DPLOG(ERROR) << "Error deallocating mach port: " << kr;
210 DPLOG(ERROR) << "Error closing fd.";
211 break;
212 case MACH:
213 kern_return_t kr = mach_port_deallocate(mach_task_self(), memory_object_);
214 if (kr != KERN_SUCCESS)
215 DPLOG(ERROR) << "Error deallocating mach port: " << kr;
216 break;
217 }
218 } 129 }
219 130
220 void SharedMemoryHandle::SetOwnershipPassesToIPC(bool ownership_passes) { 131 void SharedMemoryHandle::SetOwnershipPassesToIPC(bool ownership_passes) {
221 DCHECK_EQ(type_, MACH);
222 ownership_passes_to_ipc_ = ownership_passes; 132 ownership_passes_to_ipc_ = ownership_passes;
223 } 133 }
224 134
225 bool SharedMemoryHandle::OwnershipPassesToIPC() const { 135 bool SharedMemoryHandle::OwnershipPassesToIPC() const {
226 DCHECK_EQ(type_, MACH);
227 return ownership_passes_to_ipc_; 136 return ownership_passes_to_ipc_;
228 } 137 }
229 138
230 void SharedMemoryHandle::CopyRelevantData(const SharedMemoryHandle& handle) { 139 void SharedMemoryHandle::CopyRelevantData(const SharedMemoryHandle& handle) {
231 switch (type_) { 140 memory_object_ = handle.memory_object_;
232 case POSIX: 141 size_ = handle.size_;
233 file_descriptor_ = handle.file_descriptor_; 142 pid_ = handle.pid_;
234 break; 143 ownership_passes_to_ipc_ = handle.ownership_passes_to_ipc_;
235 case MACH:
236 memory_object_ = handle.memory_object_;
237 size_ = handle.size_;
238 pid_ = handle.pid_;
239 ownership_passes_to_ipc_ = handle.ownership_passes_to_ipc_;
240 break;
241 }
242 } 144 }
243 145
244 } // namespace base 146 } // namespace base
OLDNEW
« no previous file with comments | « base/memory/shared_memory_handle.h ('k') | base/memory/shared_memory_mac.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698