| 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 |