| 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> |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 | 76 |
| 77 *new_handle = SharedMemoryHandle(named_right, size, base::GetCurrentProcId()); | 77 *new_handle = SharedMemoryHandle(named_right, size, base::GetCurrentProcId()); |
| 78 return true; | 78 return true; |
| 79 } | 79 } |
| 80 | 80 |
| 81 | 81 |
| 82 } // namespace | 82 } // namespace |
| 83 | 83 |
| 84 SharedMemory::SharedMemory() | 84 SharedMemory::SharedMemory() |
| 85 : mapped_memory_mechanism_(SharedMemoryHandle::MACH), | 85 : mapped_memory_mechanism_(SharedMemoryHandle::MACH), |
| 86 readonly_mapped_file_(-1), | |
| 87 mapped_size_(0), | 86 mapped_size_(0), |
| 88 memory_(NULL), | 87 memory_(NULL), |
| 89 read_only_(false), | 88 read_only_(false), |
| 90 requested_size_(0) {} | 89 requested_size_(0) {} |
| 91 | 90 |
| 92 SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only) | 91 SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only) |
| 93 : shm_(handle), | 92 : shm_(handle), |
| 94 mapped_memory_mechanism_(SharedMemoryHandle::POSIX), | 93 mapped_memory_mechanism_(SharedMemoryHandle::POSIX), |
| 95 readonly_mapped_file_(-1), | |
| 96 mapped_size_(0), | 94 mapped_size_(0), |
| 97 memory_(NULL), | 95 memory_(NULL), |
| 98 read_only_(read_only), | 96 read_only_(read_only), |
| 99 requested_size_(0) {} | 97 requested_size_(0) {} |
| 100 | 98 |
| 101 SharedMemory::~SharedMemory() { | 99 SharedMemory::~SharedMemory() { |
| 102 Unmap(); | 100 Unmap(); |
| 103 Close(); | 101 Close(); |
| 104 } | 102 } |
| 105 | 103 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 if (fstat(fileno(fp.get()), &stat) != 0) | 177 if (fstat(fileno(fp.get()), &stat) != 0) |
| 180 return false; | 178 return false; |
| 181 const size_t current_size = stat.st_size; | 179 const size_t current_size = stat.st_size; |
| 182 if (current_size != options.size) { | 180 if (current_size != options.size) { |
| 183 if (HANDLE_EINTR(ftruncate(fileno(fp.get()), options.size)) != 0) | 181 if (HANDLE_EINTR(ftruncate(fileno(fp.get()), options.size)) != 0) |
| 184 return false; | 182 return false; |
| 185 } | 183 } |
| 186 requested_size_ = options.size; | 184 requested_size_ = options.size; |
| 187 | 185 |
| 188 int mapped_file = -1; | 186 int mapped_file = -1; |
| 187 int readonly_mapped_file = -1; |
| 189 result = PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file, | 188 result = PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file, |
| 190 &readonly_mapped_file_); | 189 &readonly_mapped_file); |
| 191 | |
| 192 shm_ = SharedMemoryHandle(FileDescriptor(mapped_file, false)); | 190 shm_ = SharedMemoryHandle(FileDescriptor(mapped_file, false)); |
| 191 readonly_shm_ = |
| 192 SharedMemoryHandle(FileDescriptor(readonly_mapped_file, false)); |
| 193 return result; | 193 return result; |
| 194 } | 194 } |
| 195 | 195 |
| 196 bool SharedMemory::MapAt(off_t offset, size_t bytes) { | 196 bool SharedMemory::MapAt(off_t offset, size_t bytes) { |
| 197 if (!shm_.IsValid()) | 197 if (!shm_.IsValid()) |
| 198 return false; | 198 return false; |
| 199 if (bytes > static_cast<size_t>(std::numeric_limits<int>::max())) | 199 if (bytes > static_cast<size_t>(std::numeric_limits<int>::max())) |
| 200 return false; | 200 return false; |
| 201 if (memory_) | 201 if (memory_) |
| 202 return false; | 202 return false; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 SharedMemoryHandle SharedMemory::TakeHandle() { | 247 SharedMemoryHandle SharedMemory::TakeHandle() { |
| 248 SharedMemoryHandle dup = DuplicateHandle(handle()); | 248 SharedMemoryHandle dup = DuplicateHandle(handle()); |
| 249 Close(); | 249 Close(); |
| 250 return dup; | 250 return dup; |
| 251 } | 251 } |
| 252 | 252 |
| 253 void SharedMemory::Close() { | 253 void SharedMemory::Close() { |
| 254 shm_.Close(); | 254 shm_.Close(); |
| 255 shm_ = SharedMemoryHandle(); | 255 shm_ = SharedMemoryHandle(); |
| 256 if (shm_.type_ == SharedMemoryHandle::POSIX) { | 256 if (shm_.type_ == SharedMemoryHandle::POSIX) { |
| 257 if (readonly_mapped_file_ > 0) { | 257 if (readonly_shm_.IsValid()) { |
| 258 if (IGNORE_EINTR(close(readonly_mapped_file_)) < 0) | 258 readonly_shm_.Close(); |
| 259 PLOG(ERROR) << "close"; | 259 readonly_shm_ = SharedMemoryHandle(); |
| 260 readonly_mapped_file_ = -1; | |
| 261 } | 260 } |
| 262 } | 261 } |
| 263 } | 262 } |
| 264 | 263 |
| 265 bool SharedMemory::Share(SharedMemoryHandle* new_handle, ShareMode share_mode) { | 264 SharedMemoryHandle SharedMemory::GetReadOnlyHandle() { |
| 266 if (shm_.type_ == SharedMemoryHandle::MACH) { | 265 if (shm_.type_ == SharedMemoryHandle::POSIX) { |
| 267 DCHECK(shm_.IsValid()); | 266 // We could imagine re-opening the file from /dev/fd, but that can't make it |
| 268 | 267 // readonly on Mac: https://codereview.chromium.org/27265002/#msg10. |
| 269 bool success = false; | 268 CHECK(readonly_shm_.IsValid()); |
| 270 switch (share_mode) { | 269 return readonly_shm_.Duplicate(); |
| 271 case SHARE_CURRENT_MODE: | |
| 272 *new_handle = shm_.Duplicate(); | |
| 273 success = true; | |
| 274 break; | |
| 275 case SHARE_READONLY: | |
| 276 success = MakeMachSharedMemoryHandleReadOnly(new_handle, shm_, memory_); | |
| 277 break; | |
| 278 } | |
| 279 | |
| 280 if (success) | |
| 281 new_handle->SetOwnershipPassesToIPC(true); | |
| 282 | |
| 283 return success; | |
| 284 } | 270 } |
| 285 | 271 |
| 286 int handle_to_dup = -1; | 272 DCHECK(shm_.IsValid()); |
| 287 switch (share_mode) { | 273 base::SharedMemoryHandle new_handle; |
| 288 case SHARE_CURRENT_MODE: | 274 bool success = MakeMachSharedMemoryHandleReadOnly(&new_handle, shm_, memory_); |
| 289 handle_to_dup = shm_.file_descriptor_.fd; | 275 if (success) |
| 290 break; | 276 new_handle.SetOwnershipPassesToIPC(true); |
| 291 case SHARE_READONLY: | 277 return new_handle; |
| 292 // We could imagine re-opening the file from /dev/fd, but that can't make | 278 } |
| 293 // it readonly on Mac: https://codereview.chromium.org/27265002/#msg10 | |
| 294 CHECK_GE(readonly_mapped_file_, 0); | |
| 295 handle_to_dup = readonly_mapped_file_; | |
| 296 break; | |
| 297 } | |
| 298 | 279 |
| 299 const int new_fd = HANDLE_EINTR(dup(handle_to_dup)); | 280 bool SharedMemory::Share(SharedMemoryHandle* new_handle) { |
| 300 if (new_fd < 0) { | 281 DCHECK(shm_.IsValid()); |
| 301 DPLOG(ERROR) << "dup() failed."; | 282 *new_handle = shm_.Duplicate(); |
| 302 return false; | 283 return new_handle->IsValid(); |
| 303 } | |
| 304 | |
| 305 new_handle->file_descriptor_.fd = new_fd; | |
| 306 new_handle->type_ = SharedMemoryHandle::POSIX; | |
| 307 | |
| 308 return true; | |
| 309 } | 284 } |
| 310 | 285 |
| 311 bool SharedMemory::ShareToProcessCommon(ProcessHandle process, | 286 bool SharedMemory::ShareToProcessCommon(ProcessHandle process, |
| 312 SharedMemoryHandle* new_handle, | 287 SharedMemoryHandle* new_handle, |
| 313 bool close_self, | 288 bool close_self) { |
| 314 ShareMode share_mode) { | 289 bool success = Share(new_handle); |
| 315 bool success = Share(new_handle, share_mode); | |
| 316 if (close_self) { | 290 if (close_self) { |
| 317 Unmap(); | 291 Unmap(); |
| 318 Close(); | 292 Close(); |
| 319 } | 293 } |
| 320 return success; | 294 return success; |
| 321 } | 295 } |
| 322 | 296 |
| 323 } // namespace base | 297 } // namespace base |
| OLD | NEW |