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 <sys/mman.h> | 9 #include <sys/mman.h> |
10 #include <sys/stat.h> | 10 #include <sys/stat.h> |
11 #include <sys/types.h> | 11 #include <sys/types.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/lazy_instance.h" | 16 #include "base/lazy_instance.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/posix/eintr_wrapper.h" | 18 #include "base/posix/eintr_wrapper.h" |
19 #include "base/posix/safe_strerror.h" | 19 #include "base/posix/safe_strerror.h" |
20 #include "base/process/process_metrics.h" | 20 #include "base/process/process_metrics.h" |
21 #include "base/profiler/scoped_tracker.h" | 21 #include "base/profiler/scoped_tracker.h" |
22 #include "base/scoped_generic.h" | 22 #include "base/scoped_generic.h" |
23 #include "base/strings/utf_string_conversions.h" | 23 #include "base/strings/utf_string_conversions.h" |
24 #include "base/synchronization/lock.h" | 24 #include "base/synchronization/lock.h" |
25 #include "base/threading/platform_thread.h" | 25 #include "base/threading/platform_thread.h" |
26 #include "base/threading/thread_restrictions.h" | 26 #include "base/threading/thread_restrictions.h" |
27 | 27 |
28 #if defined(OS_MACOSX) | |
29 #include "base/mac/foundation_util.h" | |
30 #endif // OS_MACOSX | |
31 | |
32 #if defined(OS_ANDROID) | 28 #if defined(OS_ANDROID) |
33 #include "base/os_compat_android.h" | 29 #include "base/os_compat_android.h" |
34 #include "third_party/ashmem/ashmem.h" | 30 #include "third_party/ashmem/ashmem.h" |
35 #endif | 31 #endif |
36 | 32 |
37 namespace base { | 33 namespace base { |
38 | 34 |
39 namespace { | 35 namespace { |
40 | 36 |
41 LazyInstance<Lock>::Leaky g_thread_lock_ = LAZY_INSTANCE_INITIALIZER; | 37 LazyInstance<Lock>::Leaky g_thread_lock_ = LAZY_INSTANCE_INITIALIZER; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 | 107 |
112 SharedMemory::SharedMemory() | 108 SharedMemory::SharedMemory() |
113 : mapped_file_(-1), | 109 : mapped_file_(-1), |
114 readonly_mapped_file_(-1), | 110 readonly_mapped_file_(-1), |
115 mapped_size_(0), | 111 mapped_size_(0), |
116 memory_(NULL), | 112 memory_(NULL), |
117 read_only_(false), | 113 read_only_(false), |
118 requested_size_(0) { | 114 requested_size_(0) { |
119 } | 115 } |
120 | 116 |
121 SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only) | 117 SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only) |
122 : mapped_file_(handle.fd), | 118 : mapped_file_(handle.fd), |
123 readonly_mapped_file_(-1), | 119 readonly_mapped_file_(-1), |
124 mapped_size_(0), | 120 mapped_size_(0), |
125 memory_(NULL), | 121 memory_(NULL), |
126 read_only_(read_only), | 122 read_only_(read_only), |
127 requested_size_(0) { | 123 requested_size_(0) { |
128 } | 124 } |
129 | 125 |
130 SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only, | 126 SharedMemory::SharedMemory(const SharedMemoryHandle& handle, |
| 127 bool read_only, |
131 ProcessHandle process) | 128 ProcessHandle process) |
132 : mapped_file_(handle.fd), | 129 : mapped_file_(handle.fd), |
133 readonly_mapped_file_(-1), | 130 readonly_mapped_file_(-1), |
134 mapped_size_(0), | 131 mapped_size_(0), |
135 memory_(NULL), | 132 memory_(NULL), |
136 read_only_(read_only), | 133 read_only_(read_only), |
137 requested_size_(0) { | 134 requested_size_(0) { |
138 // We don't handle this case yet (note the ignored parameter); let's die if | 135 // We don't handle this case yet (note the ignored parameter); let's die if |
139 // someone comes calling. | 136 // someone comes calling. |
140 NOTREACHED(); | 137 NOTREACHED(); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 if (fstat(fileno(fp.get()), &stat) != 0) | 288 if (fstat(fileno(fp.get()), &stat) != 0) |
292 return false; | 289 return false; |
293 const size_t current_size = stat.st_size; | 290 const size_t current_size = stat.st_size; |
294 if (current_size != options.size) { | 291 if (current_size != options.size) { |
295 if (HANDLE_EINTR(ftruncate(fileno(fp.get()), options.size)) != 0) | 292 if (HANDLE_EINTR(ftruncate(fileno(fp.get()), options.size)) != 0) |
296 return false; | 293 return false; |
297 } | 294 } |
298 requested_size_ = options.size; | 295 requested_size_ = options.size; |
299 } | 296 } |
300 if (fp == NULL) { | 297 if (fp == NULL) { |
301 #if !defined(OS_MACOSX) | |
302 PLOG(ERROR) << "Creating shared memory in " << path.value() << " failed"; | 298 PLOG(ERROR) << "Creating shared memory in " << path.value() << " failed"; |
303 FilePath dir = path.DirName(); | 299 FilePath dir = path.DirName(); |
304 if (access(dir.value().c_str(), W_OK | X_OK) < 0) { | 300 if (access(dir.value().c_str(), W_OK | X_OK) < 0) { |
305 PLOG(ERROR) << "Unable to access(W_OK|X_OK) " << dir.value(); | 301 PLOG(ERROR) << "Unable to access(W_OK|X_OK) " << dir.value(); |
306 if (dir.value() == "/dev/shm") { | 302 if (dir.value() == "/dev/shm") { |
307 LOG(FATAL) << "This is frequently caused by incorrect permissions on " | 303 LOG(FATAL) << "This is frequently caused by incorrect permissions on " |
308 << "/dev/shm. Try 'sudo chmod 1777 /dev/shm' to fix."; | 304 << "/dev/shm. Try 'sudo chmod 1777 /dev/shm' to fix."; |
309 } | 305 } |
310 } | 306 } |
311 #else | |
312 PLOG(ERROR) << "Creating shared memory in " << path.value() << " failed"; | |
313 #endif | |
314 return false; | 307 return false; |
315 } | 308 } |
316 | 309 |
317 return PrepareMapFile(fp.Pass(), readonly_fd.Pass()); | 310 return PrepareMapFile(fp.Pass(), readonly_fd.Pass()); |
318 } | 311 } |
319 | 312 |
320 // Our current implementation of shmem is with mmap()ing of files. | 313 // Our current implementation of shmem is with mmap()ing of files. |
321 // These files need to be deleted explicitly. | 314 // These files need to be deleted explicitly. |
322 // In practice this call is only needed for unit tests. | 315 // In practice this call is only needed for unit tests. |
323 bool SharedMemory::Delete(const std::string& name) { | 316 bool SharedMemory::Delete(const std::string& name) { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 FilePath* path) { | 463 FilePath* path) { |
471 // mem_name will be used for a filename; make sure it doesn't | 464 // mem_name will be used for a filename; make sure it doesn't |
472 // contain anything which will confuse us. | 465 // contain anything which will confuse us. |
473 DCHECK_EQ(std::string::npos, mem_name.find('/')); | 466 DCHECK_EQ(std::string::npos, mem_name.find('/')); |
474 DCHECK_EQ(std::string::npos, mem_name.find('\0')); | 467 DCHECK_EQ(std::string::npos, mem_name.find('\0')); |
475 | 468 |
476 FilePath temp_dir; | 469 FilePath temp_dir; |
477 if (!GetShmemTempDir(false, &temp_dir)) | 470 if (!GetShmemTempDir(false, &temp_dir)) |
478 return false; | 471 return false; |
479 | 472 |
480 #if !defined(OS_MACOSX) | |
481 #if defined(GOOGLE_CHROME_BUILD) | 473 #if defined(GOOGLE_CHROME_BUILD) |
482 std::string name_base = std::string("com.google.Chrome"); | 474 std::string name_base = std::string("com.google.Chrome"); |
483 #else | 475 #else |
484 std::string name_base = std::string("org.chromium.Chromium"); | 476 std::string name_base = std::string("org.chromium.Chromium"); |
485 #endif | 477 #endif |
486 #else // OS_MACOSX | |
487 std::string name_base = std::string(base::mac::BaseBundleID()); | |
488 #endif // OS_MACOSX | |
489 *path = temp_dir.AppendASCII(name_base + ".shmem." + mem_name); | 478 *path = temp_dir.AppendASCII(name_base + ".shmem." + mem_name); |
490 return true; | 479 return true; |
491 } | 480 } |
492 #endif // !defined(OS_ANDROID) | 481 #endif // !defined(OS_ANDROID) |
493 | 482 |
494 void SharedMemory::LockOrUnlockCommon(int function) { | 483 void SharedMemory::LockOrUnlockCommon(int function) { |
495 DCHECK_GE(mapped_file_, 0); | 484 DCHECK_GE(mapped_file_, 0); |
496 while (lockf(mapped_file_, function, 0) < 0) { | 485 while (lockf(mapped_file_, function, 0) < 0) { |
497 if (errno == EINTR) { | 486 if (errno == EINTR) { |
498 continue; | 487 continue; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 | 527 |
539 if (close_self) { | 528 if (close_self) { |
540 Unmap(); | 529 Unmap(); |
541 Close(); | 530 Close(); |
542 } | 531 } |
543 | 532 |
544 return true; | 533 return true; |
545 } | 534 } |
546 | 535 |
547 } // namespace base | 536 } // namespace base |
OLD | NEW |