| 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/process/process_metrics.h" | 16 #include "base/process/process_metrics.h" |
| 20 #include "base/profiler/scoped_tracker.h" | 17 #include "base/profiler/scoped_tracker.h" |
| 21 #include "base/safe_strerror_posix.h" | |
| 22 #include "base/scoped_generic.h" | 18 #include "base/scoped_generic.h" |
| 23 #include "base/strings/utf_string_conversions.h" | 19 #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 | 20 |
| 28 #if defined(OS_MACOSX) | 21 #if defined(OS_MACOSX) |
| 29 #include "base/mac/foundation_util.h" | 22 #include "base/mac/foundation_util.h" |
| 30 #endif // OS_MACOSX | 23 #endif // OS_MACOSX |
| 31 | 24 |
| 32 #if defined(OS_ANDROID) | 25 #if defined(OS_ANDROID) |
| 33 #include "base/os_compat_android.h" | 26 #include "base/os_compat_android.h" |
| 34 #include "third_party/ashmem/ashmem.h" | 27 #include "third_party/ashmem/ashmem.h" |
| 35 #endif | 28 #endif |
| 36 | 29 |
| 37 namespace base { | 30 namespace base { |
| 38 | 31 |
| 39 namespace { | 32 namespace { |
| 40 | 33 |
| 41 LazyInstance<Lock>::Leaky g_thread_lock_ = LAZY_INSTANCE_INITIALIZER; | |
| 42 | |
| 43 struct ScopedPathUnlinkerTraits { | 34 struct ScopedPathUnlinkerTraits { |
| 44 static FilePath* InvalidValue() { return nullptr; } | 35 static FilePath* InvalidValue() { return nullptr; } |
| 45 | 36 |
| 46 static void Free(FilePath* path) { | 37 static void Free(FilePath* path) { |
| 47 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466437 | 38 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466437 |
| 48 // is fixed. | 39 // is fixed. |
| 49 tracked_objects::ScopedTracker tracking_profile( | 40 tracked_objects::ScopedTracker tracking_profile( |
| 50 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 41 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 51 "466437 SharedMemory::Create::Unlink")); | 42 "466437 SharedMemory::Create::Unlink")); |
| 52 if (unlink(path->value().c_str())) | 43 if (unlink(path->value().c_str())) |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 PLOG(ERROR) << "close"; | 416 PLOG(ERROR) << "close"; |
| 426 mapped_file_ = -1; | 417 mapped_file_ = -1; |
| 427 } | 418 } |
| 428 if (readonly_mapped_file_ > 0) { | 419 if (readonly_mapped_file_ > 0) { |
| 429 if (close(readonly_mapped_file_) < 0) | 420 if (close(readonly_mapped_file_) < 0) |
| 430 PLOG(ERROR) << "close"; | 421 PLOG(ERROR) << "close"; |
| 431 readonly_mapped_file_ = -1; | 422 readonly_mapped_file_ = -1; |
| 432 } | 423 } |
| 433 } | 424 } |
| 434 | 425 |
| 435 void SharedMemory::LockDeprecated() { | |
| 436 g_thread_lock_.Get().Acquire(); | |
| 437 LockOrUnlockCommon(F_LOCK); | |
| 438 } | |
| 439 | |
| 440 void SharedMemory::UnlockDeprecated() { | |
| 441 LockOrUnlockCommon(F_ULOCK); | |
| 442 g_thread_lock_.Get().Release(); | |
| 443 } | |
| 444 | |
| 445 #if !defined(OS_ANDROID) | 426 #if !defined(OS_ANDROID) |
| 446 bool SharedMemory::PrepareMapFile(ScopedFILE fp, ScopedFD readonly_fd) { | 427 bool SharedMemory::PrepareMapFile(ScopedFILE fp, ScopedFD readonly_fd) { |
| 447 DCHECK_EQ(-1, mapped_file_); | 428 DCHECK_EQ(-1, mapped_file_); |
| 448 DCHECK_EQ(-1, readonly_mapped_file_); | 429 DCHECK_EQ(-1, readonly_mapped_file_); |
| 449 if (fp == NULL) | 430 if (fp == NULL) |
| 450 return false; | 431 return false; |
| 451 | 432 |
| 452 // This function theoretically can block on the disk, but realistically | 433 // This function theoretically can block on the disk, but realistically |
| 453 // the temporary files we create will just go into the buffer cache | 434 // the temporary files we create will just go into the buffer cache |
| 454 // and be deleted before they ever make it out to disk. | 435 // and be deleted before they ever make it out to disk. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 std::string name_base = std::string("org.chromium.Chromium"); | 484 std::string name_base = std::string("org.chromium.Chromium"); |
| 504 #endif | 485 #endif |
| 505 #else // OS_MACOSX | 486 #else // OS_MACOSX |
| 506 std::string name_base = std::string(base::mac::BaseBundleID()); | 487 std::string name_base = std::string(base::mac::BaseBundleID()); |
| 507 #endif // OS_MACOSX | 488 #endif // OS_MACOSX |
| 508 *path = temp_dir.AppendASCII(name_base + ".shmem." + mem_name); | 489 *path = temp_dir.AppendASCII(name_base + ".shmem." + mem_name); |
| 509 return true; | 490 return true; |
| 510 } | 491 } |
| 511 #endif // !defined(OS_ANDROID) | 492 #endif // !defined(OS_ANDROID) |
| 512 | 493 |
| 513 void SharedMemory::LockOrUnlockCommon(int function) { | |
| 514 DCHECK_GE(mapped_file_, 0); | |
| 515 while (lockf(mapped_file_, function, 0) < 0) { | |
| 516 if (errno == EINTR) { | |
| 517 continue; | |
| 518 } else if (errno == ENOLCK) { | |
| 519 // temporary kernel resource exaustion | |
| 520 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(500)); | |
| 521 continue; | |
| 522 } else { | |
| 523 NOTREACHED() << "lockf() failed." | |
| 524 << " function:" << function | |
| 525 << " fd:" << mapped_file_ | |
| 526 << " errno:" << errno | |
| 527 << " msg:" << safe_strerror(errno); | |
| 528 } | |
| 529 } | |
| 530 } | |
| 531 | |
| 532 bool SharedMemory::ShareToProcessCommon(ProcessHandle process, | 494 bool SharedMemory::ShareToProcessCommon(ProcessHandle process, |
| 533 SharedMemoryHandle* new_handle, | 495 SharedMemoryHandle* new_handle, |
| 534 bool close_self, | 496 bool close_self, |
| 535 ShareMode share_mode) { | 497 ShareMode share_mode) { |
| 536 int handle_to_dup = -1; | 498 int handle_to_dup = -1; |
| 537 switch(share_mode) { | 499 switch(share_mode) { |
| 538 case SHARE_CURRENT_MODE: | 500 case SHARE_CURRENT_MODE: |
| 539 handle_to_dup = mapped_file_; | 501 handle_to_dup = mapped_file_; |
| 540 break; | 502 break; |
| 541 case SHARE_READONLY: | 503 case SHARE_READONLY: |
| (...skipping 15 matching lines...) Expand all Loading... |
| 557 | 519 |
| 558 if (close_self) { | 520 if (close_self) { |
| 559 Unmap(); | 521 Unmap(); |
| 560 Close(); | 522 Close(); |
| 561 } | 523 } |
| 562 | 524 |
| 563 return true; | 525 return true; |
| 564 } | 526 } |
| 565 | 527 |
| 566 } // namespace base | 528 } // namespace base |
| OLD | NEW |