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/shared_memory.h" | 5 #include "base/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> |
(...skipping 24 matching lines...) Expand all Loading... |
35 // Paranoia. Semaphores and shared memory segments should live in different | 35 // Paranoia. Semaphores and shared memory segments should live in different |
36 // namespaces, but who knows what's out there. | 36 // namespaces, but who knows what's out there. |
37 const char kSemaphoreSuffix[] = "-sem"; | 37 const char kSemaphoreSuffix[] = "-sem"; |
38 | 38 |
39 LazyInstance<Lock>::Leaky g_thread_lock_ = LAZY_INSTANCE_INITIALIZER; | 39 LazyInstance<Lock>::Leaky g_thread_lock_ = LAZY_INSTANCE_INITIALIZER; |
40 | 40 |
41 } | 41 } |
42 | 42 |
43 SharedMemory::SharedMemory() | 43 SharedMemory::SharedMemory() |
44 : mapped_file_(-1), | 44 : mapped_file_(-1), |
| 45 inode_(0), |
45 mapped_size_(0), | 46 mapped_size_(0), |
46 inode_(0), | |
47 memory_(NULL), | 47 memory_(NULL), |
48 read_only_(false), | 48 read_only_(false), |
49 created_size_(0) { | 49 requested_size_(0) { |
50 } | 50 } |
51 | 51 |
52 SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only) | 52 SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only) |
53 : mapped_file_(handle.fd), | 53 : mapped_file_(handle.fd), |
| 54 inode_(0), |
54 mapped_size_(0), | 55 mapped_size_(0), |
55 inode_(0), | |
56 memory_(NULL), | 56 memory_(NULL), |
57 read_only_(read_only), | 57 read_only_(read_only), |
58 created_size_(0) { | 58 requested_size_(0) { |
59 struct stat st; | 59 struct stat st; |
60 if (fstat(handle.fd, &st) == 0) { | 60 if (fstat(handle.fd, &st) == 0) { |
61 // If fstat fails, then the file descriptor is invalid and we'll learn this | 61 // If fstat fails, then the file descriptor is invalid and we'll learn this |
62 // fact when Map() fails. | 62 // fact when Map() fails. |
63 inode_ = st.st_ino; | 63 inode_ = st.st_ino; |
64 } | 64 } |
65 } | 65 } |
66 | 66 |
67 SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only, | 67 SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only, |
68 ProcessHandle process) | 68 ProcessHandle process) |
69 : mapped_file_(handle.fd), | 69 : mapped_file_(handle.fd), |
| 70 inode_(0), |
70 mapped_size_(0), | 71 mapped_size_(0), |
71 inode_(0), | |
72 memory_(NULL), | 72 memory_(NULL), |
73 read_only_(read_only), | 73 read_only_(read_only), |
74 created_size_(0) { | 74 requested_size_(0) { |
75 // We don't handle this case yet (note the ignored parameter); let's die if | 75 // We don't handle this case yet (note the ignored parameter); let's die if |
76 // someone comes calling. | 76 // someone comes calling. |
77 NOTREACHED(); | 77 NOTREACHED(); |
78 } | 78 } |
79 | 79 |
80 SharedMemory::~SharedMemory() { | 80 SharedMemory::~SharedMemory() { |
81 Close(); | 81 Close(); |
82 } | 82 } |
83 | 83 |
84 // static | 84 // static |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 file_util::CloseFile(fp); | 157 file_util::CloseFile(fp); |
158 return false; | 158 return false; |
159 } | 159 } |
160 const size_t current_size = stat.st_size; | 160 const size_t current_size = stat.st_size; |
161 if (current_size != options.size) { | 161 if (current_size != options.size) { |
162 if (HANDLE_EINTR(ftruncate(fileno(fp), options.size)) != 0) { | 162 if (HANDLE_EINTR(ftruncate(fileno(fp), options.size)) != 0) { |
163 file_util::CloseFile(fp); | 163 file_util::CloseFile(fp); |
164 return false; | 164 return false; |
165 } | 165 } |
166 } | 166 } |
167 created_size_ = options.size; | 167 requested_size_ = options.size; |
168 } | 168 } |
169 if (fp == NULL) { | 169 if (fp == NULL) { |
170 #if !defined(OS_MACOSX) | 170 #if !defined(OS_MACOSX) |
171 PLOG(ERROR) << "Creating shared memory in " << path.value() << " failed"; | 171 PLOG(ERROR) << "Creating shared memory in " << path.value() << " failed"; |
172 FilePath dir = path.DirName(); | 172 FilePath dir = path.DirName(); |
173 if (access(dir.value().c_str(), W_OK | X_OK) < 0) { | 173 if (access(dir.value().c_str(), W_OK | X_OK) < 0) { |
174 PLOG(ERROR) << "Unable to access(W_OK|X_OK) " << dir.value(); | 174 PLOG(ERROR) << "Unable to access(W_OK|X_OK) " << dir.value(); |
175 if (dir.value() == "/dev/shm") { | 175 if (dir.value() == "/dev/shm") { |
176 LOG(FATAL) << "This is frequently caused by incorrect permissions on " | 176 LOG(FATAL) << "This is frequently caused by incorrect permissions on " |
177 << "/dev/shm. Try 'sudo chmod 1777 /dev/shm' to fix."; | 177 << "/dev/shm. Try 'sudo chmod 1777 /dev/shm' to fix."; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 int ashmem_bytes = ashmem_get_size_region(mapped_file_); | 228 int ashmem_bytes = ashmem_get_size_region(mapped_file_); |
229 if (ashmem_bytes < 0) | 229 if (ashmem_bytes < 0) |
230 return false; | 230 return false; |
231 | 231 |
232 DCHECK_GE(static_cast<uint32>(ashmem_bytes), bytes); | 232 DCHECK_GE(static_cast<uint32>(ashmem_bytes), bytes); |
233 // The caller wants to determine the map region size from ashmem. | 233 // The caller wants to determine the map region size from ashmem. |
234 bytes = ashmem_bytes - offset; | 234 bytes = ashmem_bytes - offset; |
235 // TODO(port): we set the created size here so that it is available in | 235 // TODO(port): we set the created size here so that it is available in |
236 // transport_dib_android.cc. We should use ashmem_get_size_region() | 236 // transport_dib_android.cc. We should use ashmem_get_size_region() |
237 // in transport_dib_android.cc. | 237 // in transport_dib_android.cc. |
238 created_size_ = ashmem_bytes; | 238 mapped_size_ = ashmem_bytes; |
239 } | 239 } |
240 #endif | 240 #endif |
241 | 241 |
242 memory_ = mmap(NULL, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE), | 242 memory_ = mmap(NULL, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE), |
243 MAP_SHARED, mapped_file_, offset); | 243 MAP_SHARED, mapped_file_, offset); |
244 | 244 |
245 bool mmap_succeeded = memory_ != (void*)-1 && memory_ != NULL; | 245 bool mmap_succeeded = memory_ != (void*)-1 && memory_ != NULL; |
246 if (mmap_succeeded) { | 246 if (mmap_succeeded) { |
| 247 #if !defined(OS_ANDROID) |
247 mapped_size_ = bytes; | 248 mapped_size_ = bytes; |
| 249 #endif |
248 DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) & | 250 DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) & |
249 (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1)); | 251 (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1)); |
250 } else { | 252 } else { |
251 memory_ = NULL; | 253 memory_ = NULL; |
252 } | 254 } |
253 | 255 |
254 return mmap_succeeded; | 256 return mmap_succeeded; |
255 } | 257 } |
256 | 258 |
257 bool SharedMemory::Unmap() { | 259 bool SharedMemory::Unmap() { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 new_handle->fd = new_fd; | 379 new_handle->fd = new_fd; |
378 new_handle->auto_close = true; | 380 new_handle->auto_close = true; |
379 | 381 |
380 if (close_self) | 382 if (close_self) |
381 Close(); | 383 Close(); |
382 | 384 |
383 return true; | 385 return true; |
384 } | 386 } |
385 | 387 |
386 } // namespace base | 388 } // namespace base |
OLD | NEW |