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> | |
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) | 26 #if defined(OS_ANDROID) |
33 #include "base/os_compat_android.h" | 27 #include "base/os_compat_android.h" |
34 #include "third_party/ashmem/ashmem.h" | 28 #include "third_party/ashmem/ashmem.h" |
35 #endif | 29 #endif |
36 | 30 |
37 namespace base { | 31 namespace base { |
38 | 32 |
39 namespace { | 33 namespace { |
40 | 34 |
41 LazyInstance<Lock>::Leaky g_thread_lock_ = LAZY_INSTANCE_INITIALIZER; | |
42 | |
43 struct ScopedPathUnlinkerTraits { | 35 struct ScopedPathUnlinkerTraits { |
44 static FilePath* InvalidValue() { return nullptr; } | 36 static FilePath* InvalidValue() { return nullptr; } |
45 | 37 |
46 static void Free(FilePath* path) { | 38 static void Free(FilePath* path) { |
47 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466437 | 39 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466437 |
48 // is fixed. | 40 // is fixed. |
49 tracked_objects::ScopedTracker tracking_profile( | 41 tracked_objects::ScopedTracker tracking_profile( |
50 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 42 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
51 "466437 SharedMemory::Create::Unlink")); | 43 "466437 SharedMemory::Create::Unlink")); |
52 if (unlink(path->value().c_str())) | 44 if (unlink(path->value().c_str())) |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 PLOG(ERROR) << "close"; | 399 PLOG(ERROR) << "close"; |
408 mapped_file_ = -1; | 400 mapped_file_ = -1; |
409 } | 401 } |
410 if (readonly_mapped_file_ > 0) { | 402 if (readonly_mapped_file_ > 0) { |
411 if (close(readonly_mapped_file_) < 0) | 403 if (close(readonly_mapped_file_) < 0) |
412 PLOG(ERROR) << "close"; | 404 PLOG(ERROR) << "close"; |
413 readonly_mapped_file_ = -1; | 405 readonly_mapped_file_ = -1; |
414 } | 406 } |
415 } | 407 } |
416 | 408 |
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) | 409 #if !defined(OS_ANDROID) |
428 bool SharedMemory::PrepareMapFile(ScopedFILE fp, ScopedFD readonly_fd) { | 410 bool SharedMemory::PrepareMapFile(ScopedFILE fp, ScopedFD readonly_fd) { |
429 DCHECK_EQ(-1, mapped_file_); | 411 DCHECK_EQ(-1, mapped_file_); |
430 DCHECK_EQ(-1, readonly_mapped_file_); | 412 DCHECK_EQ(-1, readonly_mapped_file_); |
431 if (fp == NULL) | 413 if (fp == NULL) |
432 return false; | 414 return false; |
433 | 415 |
434 // This function theoretically can block on the disk, but realistically | 416 // This function theoretically can block on the disk, but realistically |
435 // the temporary files we create will just go into the buffer cache | 417 // the temporary files we create will just go into the buffer cache |
436 // and be deleted before they ever make it out to disk. | 418 // and be deleted before they ever make it out to disk. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 std::string name_base = std::string("org.chromium.Chromium"); | 466 std::string name_base = std::string("org.chromium.Chromium"); |
485 #endif | 467 #endif |
486 #else // OS_MACOSX | 468 #else // OS_MACOSX |
487 std::string name_base = std::string(base::mac::BaseBundleID()); | 469 std::string name_base = std::string(base::mac::BaseBundleID()); |
488 #endif // OS_MACOSX | 470 #endif // OS_MACOSX |
489 *path = temp_dir.AppendASCII(name_base + ".shmem." + mem_name); | 471 *path = temp_dir.AppendASCII(name_base + ".shmem." + mem_name); |
490 return true; | 472 return true; |
491 } | 473 } |
492 #endif // !defined(OS_ANDROID) | 474 #endif // !defined(OS_ANDROID) |
493 | 475 |
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 | |
513 bool SharedMemory::ShareToProcessCommon(ProcessHandle process, | 476 bool SharedMemory::ShareToProcessCommon(ProcessHandle process, |
514 SharedMemoryHandle* new_handle, | 477 SharedMemoryHandle* new_handle, |
515 bool close_self, | 478 bool close_self, |
516 ShareMode share_mode) { | 479 ShareMode share_mode) { |
517 int handle_to_dup = -1; | 480 int handle_to_dup = -1; |
518 switch(share_mode) { | 481 switch(share_mode) { |
519 case SHARE_CURRENT_MODE: | 482 case SHARE_CURRENT_MODE: |
520 handle_to_dup = mapped_file_; | 483 handle_to_dup = mapped_file_; |
521 break; | 484 break; |
522 case SHARE_READONLY: | 485 case SHARE_READONLY: |
(...skipping 15 matching lines...) Expand all Loading... |
538 | 501 |
539 if (close_self) { | 502 if (close_self) { |
540 Unmap(); | 503 Unmap(); |
541 Close(); | 504 Close(); |
542 } | 505 } |
543 | 506 |
544 return true; | 507 return true; |
545 } | 508 } |
546 | 509 |
547 } // namespace base | 510 } // namespace base |
OLD | NEW |