OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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.h" | 5 #include "base/memory/shared_memory.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <sys/mman.h> | 10 #include <sys/mman.h> |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 int SharedMemory::GetFdFromSharedMemoryHandle( | 69 int SharedMemory::GetFdFromSharedMemoryHandle( |
70 const SharedMemoryHandle& handle) { | 70 const SharedMemoryHandle& handle) { |
71 return handle.GetHandle(); | 71 return handle.GetHandle(); |
72 } | 72 } |
73 | 73 |
74 bool SharedMemory::CreateAndMapAnonymous(size_t size) { | 74 bool SharedMemory::CreateAndMapAnonymous(size_t size) { |
75 return CreateAnonymous(size) && Map(size); | 75 return CreateAnonymous(size) && Map(size); |
76 } | 76 } |
77 | 77 |
78 #if !defined(OS_ANDROID) | 78 #if !defined(OS_ANDROID) |
79 // static | |
80 bool SharedMemory::GetSizeFromSharedMemoryHandle( | |
81 const SharedMemoryHandle& handle, | |
82 size_t* size) { | |
83 struct stat st; | |
84 if (fstat(handle.GetHandle(), &st) != 0) | |
85 return false; | |
86 if (st.st_size < 0) | |
87 return false; | |
88 *size = st.st_size; | |
89 return true; | |
90 } | |
91 | |
92 // Chromium mostly only uses the unique/private shmem as specified by | 79 // Chromium mostly only uses the unique/private shmem as specified by |
93 // "name == L"". The exception is in the StatsTable. | 80 // "name == L"". The exception is in the StatsTable. |
94 // TODO(jrg): there is no way to "clean up" all unused named shmem if | 81 // TODO(jrg): there is no way to "clean up" all unused named shmem if |
95 // we restart from a crash. (That isn't a new problem, but it is a problem.) | 82 // we restart from a crash. (That isn't a new problem, but it is a problem.) |
96 // In case we want to delete it later, it may be useful to save the value | 83 // In case we want to delete it later, it may be useful to save the value |
97 // of mem_filename after FilePathForMemoryName(). | 84 // of mem_filename after FilePathForMemoryName(). |
98 bool SharedMemory::Create(const SharedMemoryCreateOptions& options) { | 85 bool SharedMemory::Create(const SharedMemoryCreateOptions& options) { |
99 DCHECK(!shm_.IsValid()); | 86 DCHECK(!shm_.IsValid()); |
100 if (options.size == 0) return false; | 87 if (options.size == 0) return false; |
101 | 88 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 } | 189 } |
203 return false; | 190 return false; |
204 } | 191 } |
205 | 192 |
206 int mapped_file = -1; | 193 int mapped_file = -1; |
207 int readonly_mapped_file = -1; | 194 int readonly_mapped_file = -1; |
208 bool result = | 195 bool result = |
209 PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file, | 196 PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file, |
210 &readonly_mapped_file, &last_error_); | 197 &readonly_mapped_file, &last_error_); |
211 shm_ = SharedMemoryHandle(base::FileDescriptor(mapped_file, false), | 198 shm_ = SharedMemoryHandle(base::FileDescriptor(mapped_file, false), |
212 UnguessableToken::Create()); | 199 options.size, UnguessableToken::Create()); |
213 readonly_shm_ = SharedMemoryHandle( | 200 readonly_shm_ = |
214 base::FileDescriptor(readonly_mapped_file, false), shm_.GetGUID()); | 201 SharedMemoryHandle(base::FileDescriptor(readonly_mapped_file, false), |
| 202 options.size, shm_.GetGUID()); |
215 return result; | 203 return result; |
216 } | 204 } |
217 | 205 |
218 // Our current implementation of shmem is with mmap()ing of files. | 206 // Our current implementation of shmem is with mmap()ing of files. |
219 // These files need to be deleted explicitly. | 207 // These files need to be deleted explicitly. |
220 // In practice this call is only needed for unit tests. | 208 // In practice this call is only needed for unit tests. |
221 bool SharedMemory::Delete(const std::string& name) { | 209 bool SharedMemory::Delete(const std::string& name) { |
222 FilePath path; | 210 FilePath path; |
223 if (!FilePathForMemoryName(name, &path)) | 211 if (!FilePathForMemoryName(name, &path)) |
224 return false; | 212 return false; |
(...skipping 25 matching lines...) Expand all Loading... |
250 PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file, | 238 PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file, |
251 &readonly_mapped_file, &last_error_); | 239 &readonly_mapped_file, &last_error_); |
252 // This form of sharing shared memory is deprecated. https://crbug.com/345734. | 240 // This form of sharing shared memory is deprecated. https://crbug.com/345734. |
253 // However, we can't get rid of it without a significant refactor because its | 241 // However, we can't get rid of it without a significant refactor because its |
254 // used to communicate between two versions of the same service process, very | 242 // used to communicate between two versions of the same service process, very |
255 // early in the life cycle. | 243 // early in the life cycle. |
256 // Technically, we should also pass the GUID from the original shared memory | 244 // Technically, we should also pass the GUID from the original shared memory |
257 // region. We don't do that - this means that we will overcount this memory, | 245 // region. We don't do that - this means that we will overcount this memory, |
258 // which thankfully isn't relevant since Chrome only communicates with a | 246 // which thankfully isn't relevant since Chrome only communicates with a |
259 // single version of the service process. | 247 // single version of the service process. |
260 shm_ = SharedMemoryHandle(base::FileDescriptor(mapped_file, false), | 248 // We pass the size |0|, which is a dummy size and wrong, but otherwise |
| 249 // harmless. |
| 250 shm_ = SharedMemoryHandle(base::FileDescriptor(mapped_file, false), 0u, |
261 UnguessableToken::Create()); | 251 UnguessableToken::Create()); |
262 readonly_shm_ = SharedMemoryHandle( | 252 readonly_shm_ = SharedMemoryHandle( |
263 base::FileDescriptor(readonly_mapped_file, false), shm_.GetGUID()); | 253 base::FileDescriptor(readonly_mapped_file, false), 0, shm_.GetGUID()); |
264 return result; | 254 return result; |
265 } | 255 } |
266 #endif // !defined(OS_ANDROID) | 256 #endif // !defined(OS_ANDROID) |
267 | 257 |
268 bool SharedMemory::MapAt(off_t offset, size_t bytes) { | 258 bool SharedMemory::MapAt(off_t offset, size_t bytes) { |
269 if (!shm_.IsValid()) | 259 if (!shm_.IsValid()) |
270 return false; | 260 return false; |
271 | 261 |
272 if (bytes > static_cast<size_t>(std::numeric_limits<int>::max())) | 262 if (bytes > static_cast<size_t>(std::numeric_limits<int>::max())) |
273 return false; | 263 return false; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 struct stat file_stat; | 372 struct stat file_stat; |
383 if (HANDLE_EINTR( | 373 if (HANDLE_EINTR( |
384 ::fstat(static_cast<int>(handle().GetHandle()), &file_stat)) != 0) | 374 ::fstat(static_cast<int>(handle().GetHandle()), &file_stat)) != 0) |
385 return false; | 375 return false; |
386 id->first = file_stat.st_dev; | 376 id->first = file_stat.st_dev; |
387 id->second = file_stat.st_ino; | 377 id->second = file_stat.st_ino; |
388 return true; | 378 return true; |
389 } | 379 } |
390 | 380 |
391 } // namespace base | 381 } // namespace base |
OLD | NEW |