| 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 <mach/mach_vm.h> | 8 #include <mach/mach_vm.h> |
| 9 #include <stddef.h> | 9 #include <stddef.h> |
| 10 #include <sys/mman.h> | 10 #include <sys/mman.h> |
| 11 #include <sys/stat.h> | 11 #include <sys/stat.h> |
| 12 #include <unistd.h> | 12 #include <unistd.h> |
| 13 | 13 |
| 14 #include "base/files/file_util.h" | 14 #include "base/files/file_util.h" |
| 15 #include "base/files/scoped_file.h" | 15 #include "base/files/scoped_file.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/mac/mac_util.h" | 17 #include "base/mac/mac_util.h" |
| 18 #include "base/mac/scoped_mach_vm.h" | 18 #include "base/mac/scoped_mach_vm.h" |
| 19 #include "base/memory/shared_memory_helper.h" | 19 #include "base/memory/shared_memory_helper.h" |
| 20 #include "base/metrics/field_trial.h" | 20 #include "base/metrics/field_trial.h" |
| 21 #include "base/metrics/histogram_macros.h" | 21 #include "base/metrics/histogram_macros.h" |
| 22 #include "base/posix/eintr_wrapper.h" | 22 #include "base/posix/eintr_wrapper.h" |
| 23 #include "base/posix/safe_strerror.h" | 23 #include "base/posix/safe_strerror.h" |
| 24 #include "base/process/process_metrics.h" | 24 #include "base/process/process_metrics.h" |
| 25 #include "base/scoped_generic.h" | 25 #include "base/scoped_generic.h" |
| 26 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
| 27 #include "base/threading/thread_restrictions.h" | 27 #include "base/threading/thread_restrictions.h" |
| 28 #include "base/unguessable_token.h" |
| 28 #include "build/build_config.h" | 29 #include "build/build_config.h" |
| 29 | 30 |
| 30 #if defined(OS_MACOSX) | 31 #if defined(OS_MACOSX) |
| 31 #include "base/mac/foundation_util.h" | 32 #include "base/mac/foundation_util.h" |
| 32 #endif // OS_MACOSX | 33 #endif // OS_MACOSX |
| 33 | 34 |
| 34 namespace base { | 35 namespace base { |
| 35 | 36 |
| 36 namespace { | 37 namespace { |
| 37 | 38 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 67 | 68 |
| 68 // Make new memory object. | 69 // Make new memory object. |
| 69 mach_port_t named_right; | 70 mach_port_t named_right; |
| 70 kern_return_t kr = mach_make_memory_entry_64( | 71 kern_return_t kr = mach_make_memory_entry_64( |
| 71 mach_task_self(), reinterpret_cast<memory_object_size_t*>(&size), | 72 mach_task_self(), reinterpret_cast<memory_object_size_t*>(&size), |
| 72 reinterpret_cast<memory_object_offset_t>(temp_addr), VM_PROT_READ, | 73 reinterpret_cast<memory_object_offset_t>(temp_addr), VM_PROT_READ, |
| 73 &named_right, MACH_PORT_NULL); | 74 &named_right, MACH_PORT_NULL); |
| 74 if (kr != KERN_SUCCESS) | 75 if (kr != KERN_SUCCESS) |
| 75 return false; | 76 return false; |
| 76 | 77 |
| 77 *new_handle = SharedMemoryHandle(named_right, size); | 78 *new_handle = SharedMemoryHandle(named_right, size, handle.GetGUID()); |
| 78 return true; | 79 return true; |
| 79 } | 80 } |
| 80 | 81 |
| 81 | 82 |
| 82 } // namespace | 83 } // namespace |
| 83 | 84 |
| 84 SharedMemory::SharedMemory() | 85 SharedMemory::SharedMemory() |
| 85 : mapped_memory_mechanism_(SharedMemoryHandle::MACH), | 86 : mapped_memory_mechanism_(SharedMemoryHandle::MACH), |
| 86 mapped_size_(0), | 87 mapped_size_(0), |
| 87 memory_(NULL), | 88 memory_(NULL), |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 // Chromium mostly only uses the unique/private shmem as specified by | 143 // Chromium mostly only uses the unique/private shmem as specified by |
| 143 // "name == L"". The exception is in the StatsTable. | 144 // "name == L"". The exception is in the StatsTable. |
| 144 bool SharedMemory::Create(const SharedMemoryCreateOptions& options) { | 145 bool SharedMemory::Create(const SharedMemoryCreateOptions& options) { |
| 145 DCHECK(!shm_.IsValid()); | 146 DCHECK(!shm_.IsValid()); |
| 146 if (options.size == 0) return false; | 147 if (options.size == 0) return false; |
| 147 | 148 |
| 148 if (options.size > static_cast<size_t>(std::numeric_limits<int>::max())) | 149 if (options.size > static_cast<size_t>(std::numeric_limits<int>::max())) |
| 149 return false; | 150 return false; |
| 150 | 151 |
| 151 if (options.type == SharedMemoryHandle::MACH) { | 152 if (options.type == SharedMemoryHandle::MACH) { |
| 152 shm_ = SharedMemoryHandle(options.size); | 153 shm_ = SharedMemoryHandle(options.size, UnguessableToken::Create()); |
| 153 requested_size_ = options.size; | 154 requested_size_ = options.size; |
| 154 return shm_.IsValid(); | 155 return shm_.IsValid(); |
| 155 } | 156 } |
| 156 | 157 |
| 157 // This function theoretically can block on the disk. Both profiling of real | 158 // This function theoretically can block on the disk. Both profiling of real |
| 158 // users and local instrumentation shows that this is a real problem. | 159 // users and local instrumentation shows that this is a real problem. |
| 159 // https://code.google.com/p/chromium/issues/detail?id=466437 | 160 // https://code.google.com/p/chromium/issues/detail?id=466437 |
| 160 base::ThreadRestrictions::ScopedAllowIO allow_io; | 161 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 161 | 162 |
| 162 ScopedFILE fp; | 163 ScopedFILE fp; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 180 if (current_size != options.size) { | 181 if (current_size != options.size) { |
| 181 if (HANDLE_EINTR(ftruncate(fileno(fp.get()), options.size)) != 0) | 182 if (HANDLE_EINTR(ftruncate(fileno(fp.get()), options.size)) != 0) |
| 182 return false; | 183 return false; |
| 183 } | 184 } |
| 184 requested_size_ = options.size; | 185 requested_size_ = options.size; |
| 185 | 186 |
| 186 int mapped_file = -1; | 187 int mapped_file = -1; |
| 187 int readonly_mapped_file = -1; | 188 int readonly_mapped_file = -1; |
| 188 result = PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file, | 189 result = PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file, |
| 189 &readonly_mapped_file); | 190 &readonly_mapped_file); |
| 190 shm_ = SharedMemoryHandle(FileDescriptor(mapped_file, false)); | 191 shm_ = SharedMemoryHandle(FileDescriptor(mapped_file, false), |
| 191 readonly_shm_ = | 192 UnguessableToken::Create()); |
| 192 SharedMemoryHandle(FileDescriptor(readonly_mapped_file, false)); | 193 readonly_shm_ = SharedMemoryHandle( |
| 194 FileDescriptor(readonly_mapped_file, false), shm_.GetGUID()); |
| 193 return result; | 195 return result; |
| 194 } | 196 } |
| 195 | 197 |
| 196 bool SharedMemory::MapAt(off_t offset, size_t bytes) { | 198 bool SharedMemory::MapAt(off_t offset, size_t bytes) { |
| 197 if (!shm_.IsValid()) | 199 if (!shm_.IsValid()) |
| 198 return false; | 200 return false; |
| 199 if (bytes > static_cast<size_t>(std::numeric_limits<int>::max())) | 201 if (bytes > static_cast<size_t>(std::numeric_limits<int>::max())) |
| 200 return false; | 202 return false; |
| 201 if (memory_) | 203 if (memory_) |
| 202 return false; | 204 return false; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 230 } | 232 } |
| 231 | 233 |
| 232 memory_ = NULL; | 234 memory_ = NULL; |
| 233 mapped_size_ = 0; | 235 mapped_size_ = 0; |
| 234 return true; | 236 return true; |
| 235 } | 237 } |
| 236 | 238 |
| 237 SharedMemoryHandle SharedMemory::handle() const { | 239 SharedMemoryHandle SharedMemory::handle() const { |
| 238 switch (shm_.type_) { | 240 switch (shm_.type_) { |
| 239 case SharedMemoryHandle::POSIX: | 241 case SharedMemoryHandle::POSIX: |
| 240 return SharedMemoryHandle( | 242 return SharedMemoryHandle(FileDescriptor(shm_.file_descriptor_.fd, false), |
| 241 FileDescriptor(shm_.file_descriptor_.fd, false)); | 243 shm_.GetGUID()); |
| 242 case SharedMemoryHandle::MACH: | 244 case SharedMemoryHandle::MACH: |
| 243 return shm_; | 245 return shm_; |
| 244 } | 246 } |
| 245 } | 247 } |
| 246 | 248 |
| 247 SharedMemoryHandle SharedMemory::TakeHandle() { | 249 SharedMemoryHandle SharedMemory::TakeHandle() { |
| 248 SharedMemoryHandle dup = DuplicateHandle(handle()); | 250 SharedMemoryHandle dup = DuplicateHandle(handle()); |
| 249 Close(); | 251 Close(); |
| 250 return dup; | 252 return dup; |
| 251 } | 253 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 271 | 273 |
| 272 DCHECK(shm_.IsValid()); | 274 DCHECK(shm_.IsValid()); |
| 273 base::SharedMemoryHandle new_handle; | 275 base::SharedMemoryHandle new_handle; |
| 274 bool success = MakeMachSharedMemoryHandleReadOnly(&new_handle, shm_, memory_); | 276 bool success = MakeMachSharedMemoryHandleReadOnly(&new_handle, shm_, memory_); |
| 275 if (success) | 277 if (success) |
| 276 new_handle.SetOwnershipPassesToIPC(true); | 278 new_handle.SetOwnershipPassesToIPC(true); |
| 277 return new_handle; | 279 return new_handle; |
| 278 } | 280 } |
| 279 | 281 |
| 280 } // namespace base | 282 } // namespace base |
| OLD | NEW |