Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: base/memory/shared_memory_mac.cc

Issue 1641513004: Update //base to chromium 9659b08ea5a34f889dc4166217f438095ddc10d2 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/memory/shared_memory_handle_mac.cc ('k') | base/memory/shared_memory_nacl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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>
8 #include <fcntl.h> 7 #include <fcntl.h>
9 #include <sys/mman.h> 8 #include <sys/mman.h>
10 #include <sys/stat.h> 9 #include <sys/stat.h>
11 #include <sys/types.h>
12 #include <unistd.h> 10 #include <unistd.h>
13 11
14 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
15 #include "base/files/scoped_file.h" 13 #include "base/files/scoped_file.h"
16 #include "base/lazy_instance.h"
17 #include "base/logging.h" 14 #include "base/logging.h"
18 #include "base/posix/eintr_wrapper.h" 15 #include "base/posix/eintr_wrapper.h"
19 #include "base/posix/safe_strerror.h" 16 #include "base/posix/safe_strerror.h"
20 #include "base/process/process_metrics.h" 17 #include "base/process/process_metrics.h"
21 #include "base/profiler/scoped_tracker.h" 18 #include "base/profiler/scoped_tracker.h"
22 #include "base/scoped_generic.h" 19 #include "base/scoped_generic.h"
23 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
24 #include "base/synchronization/lock.h"
25 #include "base/threading/platform_thread.h"
26 #include "base/threading/thread_restrictions.h"
27 21
28 #if defined(OS_MACOSX) 22 #if defined(OS_MACOSX)
29 #include "base/mac/foundation_util.h" 23 #include "base/mac/foundation_util.h"
30 #endif // OS_MACOSX 24 #endif // OS_MACOSX
31 25
32 #if defined(OS_ANDROID)
33 #include "base/os_compat_android.h"
34 #include "third_party/ashmem/ashmem.h"
35 #endif
36
37 namespace base { 26 namespace base {
38 27
39 namespace { 28 namespace {
40 29
41 LazyInstance<Lock>::Leaky g_thread_lock_ = LAZY_INSTANCE_INITIALIZER;
42
43 struct ScopedPathUnlinkerTraits { 30 struct ScopedPathUnlinkerTraits {
44 static FilePath* InvalidValue() { return nullptr; } 31 static FilePath* InvalidValue() { return nullptr; }
45 32
46 static void Free(FilePath* path) { 33 static void Free(FilePath* path) {
47 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466437 34 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466437
48 // is fixed. 35 // is fixed.
49 tracked_objects::ScopedTracker tracking_profile( 36 tracked_objects::ScopedTracker tracking_profile(
50 FROM_HERE_WITH_EXPLICIT_FUNCTION( 37 FROM_HERE_WITH_EXPLICIT_FUNCTION(
51 "466437 SharedMemory::Create::Unlink")); 38 "466437 SharedMemory::Create::Unlink"));
52 if (unlink(path->value().c_str())) 39 if (unlink(path->value().c_str()))
53 PLOG(WARNING) << "unlink"; 40 PLOG(WARNING) << "unlink";
54 } 41 }
55 }; 42 };
56 43
57 // Unlinks the FilePath when the object is destroyed. 44 // Unlinks the FilePath when the object is destroyed.
58 typedef ScopedGeneric<FilePath*, ScopedPathUnlinkerTraits> ScopedPathUnlinker; 45 typedef ScopedGeneric<FilePath*, ScopedPathUnlinkerTraits> ScopedPathUnlinker;
59 46
60 #if !defined(OS_ANDROID)
61 // Makes a temporary file, fdopens it, and then unlinks it. |fp| is populated 47 // Makes a temporary file, fdopens it, and then unlinks it. |fp| is populated
62 // with the fdopened FILE. |readonly_fd| is populated with the opened fd if 48 // with the fdopened FILE. |readonly_fd| is populated with the opened fd if
63 // options.share_read_only is true. |path| is populated with the location of 49 // options.share_read_only is true. |path| is populated with the location of
64 // the file before it was unlinked. 50 // the file before it was unlinked.
65 // Returns false if there's an unhandled failure. 51 // Returns false if there's an unhandled failure.
66 bool CreateAnonymousSharedMemory(const SharedMemoryCreateOptions& options, 52 bool CreateAnonymousSharedMemory(const SharedMemoryCreateOptions& options,
67 ScopedFILE* fp, 53 ScopedFILE* fp,
68 ScopedFD* readonly_fd, 54 ScopedFD* readonly_fd,
69 FilePath* path) { 55 FilePath* path) {
70 // It doesn't make sense to have a open-existing private piece of shmem 56 // It doesn't make sense to have a open-existing private piece of shmem
(...skipping 28 matching lines...) Expand all
99 readonly_fd->reset(HANDLE_EINTR(open(path->value().c_str(), O_RDONLY))); 85 readonly_fd->reset(HANDLE_EINTR(open(path->value().c_str(), O_RDONLY)));
100 if (!readonly_fd->is_valid()) { 86 if (!readonly_fd->is_valid()) {
101 DPLOG(ERROR) << "open(\"" << path->value() << "\", O_RDONLY) failed"; 87 DPLOG(ERROR) << "open(\"" << path->value() << "\", O_RDONLY) failed";
102 fp->reset(); 88 fp->reset();
103 return false; 89 return false;
104 } 90 }
105 } 91 }
106 } 92 }
107 return true; 93 return true;
108 } 94 }
109 #endif // !defined(OS_ANDROID)
110 } 95 }
111 96
112 SharedMemory::SharedMemory() 97 SharedMemory::SharedMemory()
113 : mapped_file_(-1), 98 : mapped_file_(-1),
114 readonly_mapped_file_(-1), 99 readonly_mapped_file_(-1),
115 mapped_size_(0), 100 mapped_size_(0),
116 memory_(NULL), 101 memory_(NULL),
117 read_only_(false), 102 read_only_(false),
118 requested_size_(0) { 103 requested_size_(0) {}
119 }
120 104
121 SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only) 105 SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only)
122 : mapped_file_(handle.fd), 106 : mapped_file_(GetFdFromSharedMemoryHandle(handle)),
123 readonly_mapped_file_(-1), 107 readonly_mapped_file_(-1),
124 mapped_size_(0), 108 mapped_size_(0),
125 memory_(NULL), 109 memory_(NULL),
126 read_only_(read_only), 110 read_only_(read_only),
127 requested_size_(0) { 111 requested_size_(0) {}
128 }
129 112
130 SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only, 113 SharedMemory::SharedMemory(const SharedMemoryHandle& handle,
114 bool read_only,
131 ProcessHandle process) 115 ProcessHandle process)
132 : mapped_file_(handle.fd), 116 : mapped_file_(GetFdFromSharedMemoryHandle(handle)),
133 readonly_mapped_file_(-1), 117 readonly_mapped_file_(-1),
134 mapped_size_(0), 118 mapped_size_(0),
135 memory_(NULL), 119 memory_(NULL),
136 read_only_(read_only), 120 read_only_(read_only),
137 requested_size_(0) { 121 requested_size_(0) {
138 // We don't handle this case yet (note the ignored parameter); let's die if 122 // We don't handle this case yet (note the ignored parameter); let's die if
139 // someone comes calling. 123 // someone comes calling.
140 NOTREACHED(); 124 NOTREACHED();
141 } 125 }
142 126
143 SharedMemory::~SharedMemory() { 127 SharedMemory::~SharedMemory() {
144 Unmap(); 128 Unmap();
145 Close(); 129 Close();
146 } 130 }
147 131
148 // static 132 // static
149 bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) { 133 bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) {
150 return handle.fd >= 0; 134 return handle.IsValid();
151 } 135 }
152 136
153 // static 137 // static
154 SharedMemoryHandle SharedMemory::NULLHandle() { 138 SharedMemoryHandle SharedMemory::NULLHandle() {
155 return SharedMemoryHandle(); 139 return SharedMemoryHandle();
156 } 140 }
157 141
158 // static 142 // static
159 void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) { 143 void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) {
160 DCHECK_GE(handle.fd, 0); 144 DCHECK_GE(GetFdFromSharedMemoryHandle(handle), 0);
161 if (close(handle.fd) < 0) 145 if (close(GetFdFromSharedMemoryHandle(handle)) < 0)
162 DPLOG(ERROR) << "close"; 146 DPLOG(ERROR) << "close";
163 } 147 }
164 148
165 // static 149 // static
166 size_t SharedMemory::GetHandleLimit() { 150 size_t SharedMemory::GetHandleLimit() {
167 return base::GetMaxFds(); 151 return base::GetMaxFds();
168 } 152 }
169 153
170 // static 154 // static
171 SharedMemoryHandle SharedMemory::DuplicateHandle( 155 SharedMemoryHandle SharedMemory::DuplicateHandle(
172 const SharedMemoryHandle& handle) { 156 const SharedMemoryHandle& handle) {
173 int duped_handle = HANDLE_EINTR(dup(handle.fd)); 157 return handle.Duplicate();
174 if (duped_handle < 0)
175 return base::SharedMemory::NULLHandle();
176 return base::FileDescriptor(duped_handle, true);
177 } 158 }
178 159
179 // static 160 // static
180 int SharedMemory::GetFdFromSharedMemoryHandle( 161 int SharedMemory::GetFdFromSharedMemoryHandle(
181 const SharedMemoryHandle& handle) { 162 const SharedMemoryHandle& handle) {
182 return handle.fd; 163 return handle.GetFileDescriptor().fd;
183 } 164 }
184 165
185 bool SharedMemory::CreateAndMapAnonymous(size_t size) { 166 bool SharedMemory::CreateAndMapAnonymous(size_t size) {
186 return CreateAnonymous(size) && Map(size); 167 return CreateAnonymous(size) && Map(size);
187 } 168 }
188 169
189 #if !defined(OS_ANDROID)
190 // static 170 // static
191 int SharedMemory::GetSizeFromSharedMemoryHandle( 171 int SharedMemory::GetSizeFromSharedMemoryHandle(
192 const SharedMemoryHandle& handle) { 172 const SharedMemoryHandle& handle) {
193 struct stat st; 173 struct stat st;
194 if (fstat(handle.fd, &st) != 0) 174 if (fstat(GetFdFromSharedMemoryHandle(handle), &st) != 0)
195 return -1; 175 return -1;
196 return st.st_size; 176 return st.st_size;
197 } 177 }
198 178
199 // Chromium mostly only uses the unique/private shmem as specified by 179 // Chromium mostly only uses the unique/private shmem as specified by
200 // "name == L"". The exception is in the StatsTable. 180 // "name == L"". The exception is in the StatsTable.
201 // TODO(jrg): there is no way to "clean up" all unused named shmem if 181 // TODO(jrg): there is no way to "clean up" all unused named shmem if
202 // we restart from a crash. (That isn't a new problem, but it is a problem.) 182 // we restart from a crash. (That isn't a new problem, but it is a problem.)
203 // In case we want to delete it later, it may be useful to save the value 183 // In case we want to delete it later, it may be useful to save the value
204 // of mem_filename after FilePathForMemoryName(). 184 // of mem_filename after FilePathForMemoryName().
205 bool SharedMemory::Create(const SharedMemoryCreateOptions& options) { 185 bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
206 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466437 186 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466437
207 // is fixed. 187 // is fixed.
208 tracked_objects::ScopedTracker tracking_profile1( 188 tracked_objects::ScopedTracker tracking_profile1(
209 FROM_HERE_WITH_EXPLICIT_FUNCTION( 189 FROM_HERE_WITH_EXPLICIT_FUNCTION("466437 SharedMemory::Create::Start"));
210 "466437 SharedMemory::Create::Start"));
211 DCHECK_EQ(-1, mapped_file_); 190 DCHECK_EQ(-1, mapped_file_);
212 if (options.size == 0) return false; 191 if (options.size == 0)
192 return false;
213 193
214 if (options.size > static_cast<size_t>(std::numeric_limits<int>::max())) 194 if (options.size > static_cast<size_t>(std::numeric_limits<int>::max()))
215 return false; 195 return false;
216 196
217 // This function theoretically can block on the disk, but realistically 197 // This function theoretically can block on the disk, but realistically
218 // the temporary files we create will just go into the buffer cache 198 // the temporary files we create will just go into the buffer cache
219 // and be deleted before they ever make it out to disk. 199 // and be deleted before they ever make it out to disk.
220 base::ThreadRestrictions::ScopedAllowIO allow_io; 200 base::ThreadRestrictions::ScopedAllowIO allow_io;
221 201
222 ScopedFILE fp; 202 ScopedFILE fp;
(...skipping 27 matching lines...) Expand all
250 // is opened, so O_NOFOLLOW is passed to open(). 230 // is opened, so O_NOFOLLOW is passed to open().
251 fd = HANDLE_EINTR( 231 fd = HANDLE_EINTR(
252 open(path.value().c_str(), O_RDWR | O_APPEND | O_NOFOLLOW)); 232 open(path.value().c_str(), O_RDWR | O_APPEND | O_NOFOLLOW));
253 233
254 // Check that the current user owns the file. 234 // Check that the current user owns the file.
255 // If uid != euid, then a more complex permission model is used and this 235 // If uid != euid, then a more complex permission model is used and this
256 // API is not appropriate. 236 // API is not appropriate.
257 const uid_t real_uid = getuid(); 237 const uid_t real_uid = getuid();
258 const uid_t effective_uid = geteuid(); 238 const uid_t effective_uid = geteuid();
259 struct stat sb; 239 struct stat sb;
260 if (fd >= 0 && 240 if (fd >= 0 && (fstat(fd, &sb) != 0 || sb.st_uid != real_uid ||
261 (fstat(fd, &sb) != 0 || sb.st_uid != real_uid || 241 sb.st_uid != effective_uid)) {
262 sb.st_uid != effective_uid)) { 242 LOG(ERROR) << "Invalid owner when opening existing shared memory file.";
263 LOG(ERROR) <<
264 "Invalid owner when opening existing shared memory file.";
265 close(fd); 243 close(fd);
266 return false; 244 return false;
267 } 245 }
268 246
269 // An existing file was opened, so its size should not be fixed. 247 // An existing file was opened, so its size should not be fixed.
270 fix_size = false; 248 fix_size = false;
271 } 249 }
272 250
273 if (options.share_read_only) { 251 if (options.share_read_only) {
274 // Also open as readonly so that we can ShareReadOnlyToProcess. 252 // Also open as readonly so that we can ShareReadOnlyToProcess.
(...skipping 16 matching lines...) Expand all
291 if (fstat(fileno(fp.get()), &stat) != 0) 269 if (fstat(fileno(fp.get()), &stat) != 0)
292 return false; 270 return false;
293 const size_t current_size = stat.st_size; 271 const size_t current_size = stat.st_size;
294 if (current_size != options.size) { 272 if (current_size != options.size) {
295 if (HANDLE_EINTR(ftruncate(fileno(fp.get()), options.size)) != 0) 273 if (HANDLE_EINTR(ftruncate(fileno(fp.get()), options.size)) != 0)
296 return false; 274 return false;
297 } 275 }
298 requested_size_ = options.size; 276 requested_size_ = options.size;
299 } 277 }
300 if (fp == NULL) { 278 if (fp == NULL) {
301 #if !defined(OS_MACOSX)
302 PLOG(ERROR) << "Creating shared memory in " << path.value() << " failed"; 279 PLOG(ERROR) << "Creating shared memory in " << path.value() << " failed";
303 FilePath dir = path.DirName();
304 if (access(dir.value().c_str(), W_OK | X_OK) < 0) {
305 PLOG(ERROR) << "Unable to access(W_OK|X_OK) " << dir.value();
306 if (dir.value() == "/dev/shm") {
307 LOG(FATAL) << "This is frequently caused by incorrect permissions on "
308 << "/dev/shm. Try 'sudo chmod 1777 /dev/shm' to fix.";
309 }
310 }
311 #else
312 PLOG(ERROR) << "Creating shared memory in " << path.value() << " failed";
313 #endif
314 return false; 280 return false;
315 } 281 }
316 282
317 return PrepareMapFile(fp.Pass(), readonly_fd.Pass()); 283 return PrepareMapFile(fp.Pass(), readonly_fd.Pass());
318 } 284 }
319 285
320 // Our current implementation of shmem is with mmap()ing of files. 286 // Our current implementation of shmem is with mmap()ing of files.
321 // These files need to be deleted explicitly. 287 // These files need to be deleted explicitly.
322 // In practice this call is only needed for unit tests. 288 // In practice this call is only needed for unit tests.
323 bool SharedMemory::Delete(const std::string& name) { 289 bool SharedMemory::Delete(const std::string& name) {
324 FilePath path; 290 FilePath path;
325 if (!FilePathForMemoryName(name, &path)) 291 if (!FilePathForMemoryName(name, &path))
326 return false; 292 return false;
327 293
328 if (PathExists(path)) 294 if (PathExists(path))
329 return base::DeleteFile(path, false); 295 return base::DeleteFile(path, false);
330 296
331 // Doesn't exist, so success. 297 // Doesn't exist, so success.
332 return true; 298 return true;
333 } 299 }
334 300
335 bool SharedMemory::Open(const std::string& name, bool read_only) { 301 bool SharedMemory::Open(const std::string& name, bool read_only) {
336 FilePath path; 302 FilePath path;
337 if (!FilePathForMemoryName(name, &path)) 303 if (!FilePathForMemoryName(name, &path))
338 return false; 304 return false;
339 305
340 read_only_ = read_only; 306 read_only_ = read_only;
341 307
342 const char *mode = read_only ? "r" : "r+"; 308 const char* mode = read_only ? "r" : "r+";
343 ScopedFILE fp(base::OpenFile(path, mode)); 309 ScopedFILE fp(base::OpenFile(path, mode));
344 ScopedFD readonly_fd(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY))); 310 ScopedFD readonly_fd(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY)));
345 if (!readonly_fd.is_valid()) { 311 if (!readonly_fd.is_valid()) {
346 DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed"; 312 DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed";
347 return false; 313 return false;
348 } 314 }
349 return PrepareMapFile(fp.Pass(), readonly_fd.Pass()); 315 return PrepareMapFile(fp.Pass(), readonly_fd.Pass());
350 } 316 }
351 #endif // !defined(OS_ANDROID)
352 317
353 bool SharedMemory::MapAt(off_t offset, size_t bytes) { 318 bool SharedMemory::MapAt(off_t offset, size_t bytes) {
354 if (mapped_file_ == -1) 319 if (mapped_file_ == -1)
355 return false; 320 return false;
356 321
357 if (bytes > static_cast<size_t>(std::numeric_limits<int>::max())) 322 if (bytes > static_cast<size_t>(std::numeric_limits<int>::max()))
358 return false; 323 return false;
359 324
360 if (memory_) 325 if (memory_)
361 return false; 326 return false;
362 327
363 #if defined(OS_ANDROID)
364 // On Android, Map can be called with a size and offset of zero to use the
365 // ashmem-determined size.
366 if (bytes == 0) {
367 DCHECK_EQ(0, offset);
368 int ashmem_bytes = ashmem_get_size_region(mapped_file_);
369 if (ashmem_bytes < 0)
370 return false;
371 bytes = ashmem_bytes;
372 }
373 #endif
374
375 memory_ = mmap(NULL, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE), 328 memory_ = mmap(NULL, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE),
376 MAP_SHARED, mapped_file_, offset); 329 MAP_SHARED, mapped_file_, offset);
377 330
378 bool mmap_succeeded = memory_ != (void*)-1 && memory_ != NULL; 331 bool mmap_succeeded = memory_ != (void*)-1 && memory_ != NULL;
379 if (mmap_succeeded) { 332 if (mmap_succeeded) {
380 mapped_size_ = bytes; 333 mapped_size_ = bytes;
381 DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) & 334 DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) &
382 (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1)); 335 (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1));
383 } else { 336 } else {
384 memory_ = NULL; 337 memory_ = NULL;
385 } 338 }
386 339
387 return mmap_succeeded; 340 return mmap_succeeded;
388 } 341 }
389 342
390 bool SharedMemory::Unmap() { 343 bool SharedMemory::Unmap() {
391 if (memory_ == NULL) 344 if (memory_ == NULL)
392 return false; 345 return false;
393 346
394 munmap(memory_, mapped_size_); 347 munmap(memory_, mapped_size_);
395 memory_ = NULL; 348 memory_ = NULL;
396 mapped_size_ = 0; 349 mapped_size_ = 0;
397 return true; 350 return true;
398 } 351 }
399 352
400 SharedMemoryHandle SharedMemory::handle() const { 353 SharedMemoryHandle SharedMemory::handle() const {
401 return FileDescriptor(mapped_file_, false); 354 return SharedMemoryHandle(mapped_file_, false);
402 } 355 }
403 356
404 void SharedMemory::Close() { 357 void SharedMemory::Close() {
405 if (mapped_file_ > 0) { 358 if (mapped_file_ > 0) {
406 if (close(mapped_file_) < 0) 359 if (close(mapped_file_) < 0)
407 PLOG(ERROR) << "close"; 360 PLOG(ERROR) << "close";
408 mapped_file_ = -1; 361 mapped_file_ = -1;
409 } 362 }
410 if (readonly_mapped_file_ > 0) { 363 if (readonly_mapped_file_ > 0) {
411 if (close(readonly_mapped_file_) < 0) 364 if (close(readonly_mapped_file_) < 0)
412 PLOG(ERROR) << "close"; 365 PLOG(ERROR) << "close";
413 readonly_mapped_file_ = -1; 366 readonly_mapped_file_ = -1;
414 } 367 }
415 } 368 }
416 369
417 void SharedMemory::LockDeprecated() {
418 g_thread_lock_.Get().Acquire();
419 LockOrUnlockCommon(F_LOCK);
420 }
421
422 void SharedMemory::UnlockDeprecated() {
423 LockOrUnlockCommon(F_ULOCK);
424 g_thread_lock_.Get().Release();
425 }
426
427 #if !defined(OS_ANDROID)
428 bool SharedMemory::PrepareMapFile(ScopedFILE fp, ScopedFD readonly_fd) { 370 bool SharedMemory::PrepareMapFile(ScopedFILE fp, ScopedFD readonly_fd) {
429 DCHECK_EQ(-1, mapped_file_); 371 DCHECK_EQ(-1, mapped_file_);
430 DCHECK_EQ(-1, readonly_mapped_file_); 372 DCHECK_EQ(-1, readonly_mapped_file_);
431 if (fp == NULL) 373 if (fp == NULL)
432 return false; 374 return false;
433 375
434 // This function theoretically can block on the disk, but realistically 376 // This function theoretically can block on the disk, but realistically
435 // the temporary files we create will just go into the buffer cache 377 // the temporary files we create will just go into the buffer cache
436 // and be deleted before they ever make it out to disk. 378 // and be deleted before they ever make it out to disk.
437 base::ThreadRestrictions::ScopedAllowIO allow_io; 379 base::ThreadRestrictions::ScopedAllowIO allow_io;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 FilePath* path) { 412 FilePath* path) {
471 // mem_name will be used for a filename; make sure it doesn't 413 // mem_name will be used for a filename; make sure it doesn't
472 // contain anything which will confuse us. 414 // contain anything which will confuse us.
473 DCHECK_EQ(std::string::npos, mem_name.find('/')); 415 DCHECK_EQ(std::string::npos, mem_name.find('/'));
474 DCHECK_EQ(std::string::npos, mem_name.find('\0')); 416 DCHECK_EQ(std::string::npos, mem_name.find('\0'));
475 417
476 FilePath temp_dir; 418 FilePath temp_dir;
477 if (!GetShmemTempDir(false, &temp_dir)) 419 if (!GetShmemTempDir(false, &temp_dir))
478 return false; 420 return false;
479 421
480 #if !defined(OS_MACOSX)
481 #if defined(GOOGLE_CHROME_BUILD)
482 std::string name_base = std::string("com.google.Chrome");
483 #else
484 std::string name_base = std::string("org.chromium.Chromium");
485 #endif
486 #else // OS_MACOSX
487 std::string name_base = std::string(base::mac::BaseBundleID()); 422 std::string name_base = std::string(base::mac::BaseBundleID());
488 #endif // OS_MACOSX
489 *path = temp_dir.AppendASCII(name_base + ".shmem." + mem_name); 423 *path = temp_dir.AppendASCII(name_base + ".shmem." + mem_name);
490 return true; 424 return true;
491 } 425 }
492 #endif // !defined(OS_ANDROID)
493
494 void SharedMemory::LockOrUnlockCommon(int function) {
495 DCHECK_GE(mapped_file_, 0);
496 while (lockf(mapped_file_, function, 0) < 0) {
497 if (errno == EINTR) {
498 continue;
499 } else if (errno == ENOLCK) {
500 // temporary kernel resource exaustion
501 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(500));
502 continue;
503 } else {
504 NOTREACHED() << "lockf() failed."
505 << " function:" << function
506 << " fd:" << mapped_file_
507 << " errno:" << errno
508 << " msg:" << base::safe_strerror(errno);
509 }
510 }
511 }
512 426
513 bool SharedMemory::ShareToProcessCommon(ProcessHandle process, 427 bool SharedMemory::ShareToProcessCommon(ProcessHandle process,
514 SharedMemoryHandle* new_handle, 428 SharedMemoryHandle* new_handle,
515 bool close_self, 429 bool close_self,
516 ShareMode share_mode) { 430 ShareMode share_mode) {
517 int handle_to_dup = -1; 431 int handle_to_dup = -1;
518 switch(share_mode) { 432 switch (share_mode) {
519 case SHARE_CURRENT_MODE: 433 case SHARE_CURRENT_MODE:
520 handle_to_dup = mapped_file_; 434 handle_to_dup = mapped_file_;
521 break; 435 break;
522 case SHARE_READONLY: 436 case SHARE_READONLY:
523 // We could imagine re-opening the file from /dev/fd, but that can't make 437 // We could imagine re-opening the file from /dev/fd, but that can't make
524 // it readonly on Mac: https://codereview.chromium.org/27265002/#msg10 438 // it readonly on Mac: https://codereview.chromium.org/27265002/#msg10
525 CHECK_GE(readonly_mapped_file_, 0); 439 CHECK_GE(readonly_mapped_file_, 0);
526 handle_to_dup = readonly_mapped_file_; 440 handle_to_dup = readonly_mapped_file_;
527 break; 441 break;
528 } 442 }
529 443
530 const int new_fd = HANDLE_EINTR(dup(handle_to_dup)); 444 const int new_fd = HANDLE_EINTR(dup(handle_to_dup));
531 if (new_fd < 0) { 445 if (new_fd < 0) {
532 DPLOG(ERROR) << "dup() failed."; 446 DPLOG(ERROR) << "dup() failed.";
533 return false; 447 return false;
534 } 448 }
535 449
536 new_handle->fd = new_fd; 450 new_handle->SetFileHandle(new_fd, true);
537 new_handle->auto_close = true;
538 451
539 if (close_self) { 452 if (close_self) {
540 Unmap(); 453 Unmap();
541 Close(); 454 Close();
542 } 455 }
543 456
544 return true; 457 return true;
545 } 458 }
546 459
547 } // namespace base 460 } // namespace base
OLDNEW
« no previous file with comments | « base/memory/shared_memory_handle_mac.cc ('k') | base/memory/shared_memory_nacl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698