| OLD | NEW |
| 1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved. | 1 // Copyright (c) 2011 The LevelDB 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. See the AUTHORS file for names of contributors. | 3 // found in the LICENSE file. See the AUTHORS file for names of contributors. |
| 4 | 4 |
| 5 #include "third_party/leveldatabase/env_chromium.h" | 5 #include "third_party/leveldatabase/env_chromium.h" |
| 6 | 6 |
| 7 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
| 8 #include <dirent.h> | 8 #include <dirent.h> |
| 9 #include <sys/types.h> | 9 #include <sys/types.h> |
| 10 #endif | 10 #endif |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 int saved_errno = errno; | 88 int saved_errno = errno; |
| 89 closedir(dir); | 89 closedir(dir); |
| 90 if (readdir_result != 0) | 90 if (readdir_result != 0) |
| 91 return base::File::OSErrorToFileError(saved_errno); | 91 return base::File::OSErrorToFileError(saved_errno); |
| 92 return base::File::FILE_OK; | 92 return base::File::FILE_OK; |
| 93 #endif | 93 #endif |
| 94 } | 94 } |
| 95 | 95 |
| 96 class ChromiumFileLock : public FileLock { | 96 class ChromiumFileLock : public FileLock { |
| 97 public: | 97 public: |
| 98 ::base::File file_; | 98 base::File file_; |
| 99 std::string name_; | 99 std::string name_; |
| 100 }; | 100 }; |
| 101 | 101 |
| 102 class Retrier { | 102 class Retrier { |
| 103 public: | 103 public: |
| 104 Retrier(MethodID method, RetrierProvider* provider) | 104 Retrier(MethodID method, RetrierProvider* provider) |
| 105 : start_(base::TimeTicks::Now()), | 105 : start_(base::TimeTicks::Now()), |
| 106 limit_(start_ + base::TimeDelta::FromMilliseconds( | 106 limit_(start_ + base::TimeDelta::FromMilliseconds( |
| 107 provider->MaxRetryTimeMillis())), | 107 provider->MaxRetryTimeMillis())), |
| 108 last_(start_), | 108 last_(start_), |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 | 177 |
| 178 private: | 178 private: |
| 179 std::string filename_; | 179 std::string filename_; |
| 180 scoped_ptr<base::File> file_; | 180 scoped_ptr<base::File> file_; |
| 181 const UMALogger* uma_logger_; | 181 const UMALogger* uma_logger_; |
| 182 }; | 182 }; |
| 183 | 183 |
| 184 class ChromiumRandomAccessFile : public leveldb::RandomAccessFile { | 184 class ChromiumRandomAccessFile : public leveldb::RandomAccessFile { |
| 185 public: | 185 public: |
| 186 ChromiumRandomAccessFile(const std::string& fname, | 186 ChromiumRandomAccessFile(const std::string& fname, |
| 187 ::base::File file, | 187 base::File file, |
| 188 const UMALogger* uma_logger) | 188 const UMALogger* uma_logger) |
| 189 : filename_(fname), file_(file.Pass()), uma_logger_(uma_logger) {} | 189 : filename_(fname), file_(file.Pass()), uma_logger_(uma_logger) {} |
| 190 virtual ~ChromiumRandomAccessFile() {} | 190 virtual ~ChromiumRandomAccessFile() {} |
| 191 | 191 |
| 192 Status Read(uint64_t offset, | 192 Status Read(uint64_t offset, |
| 193 size_t n, | 193 size_t n, |
| 194 Slice* result, | 194 Slice* result, |
| 195 char* scratch) const override { | 195 char* scratch) const override { |
| 196 Status s; | 196 Status s; |
| 197 int r = file_.Read(offset, scratch, n); | 197 int r = file_.Read(offset, scratch, n); |
| 198 *result = Slice(scratch, (r < 0) ? 0 : r); | 198 *result = Slice(scratch, (r < 0) ? 0 : r); |
| 199 if (r < 0) { | 199 if (r < 0) { |
| 200 // An error: return a non-ok status | 200 // An error: return a non-ok status |
| 201 s = MakeIOError(filename_, "Could not perform read", | 201 s = MakeIOError(filename_, "Could not perform read", |
| 202 kRandomAccessFileRead); | 202 kRandomAccessFileRead); |
| 203 uma_logger_->RecordErrorAt(kRandomAccessFileRead); | 203 uma_logger_->RecordErrorAt(kRandomAccessFileRead); |
| 204 } | 204 } |
| 205 return s; | 205 return s; |
| 206 } | 206 } |
| 207 | 207 |
| 208 private: | 208 private: |
| 209 std::string filename_; | 209 std::string filename_; |
| 210 mutable ::base::File file_; | 210 mutable base::File file_; |
| 211 const UMALogger* uma_logger_; | 211 const UMALogger* uma_logger_; |
| 212 }; | 212 }; |
| 213 | 213 |
| 214 class ChromiumWritableFile : public leveldb::WritableFile { | 214 class ChromiumWritableFile : public leveldb::WritableFile { |
| 215 public: | 215 public: |
| 216 ChromiumWritableFile(const std::string& fname, | 216 ChromiumWritableFile(const std::string& fname, |
| 217 base::File* f, | 217 base::File* f, |
| 218 const UMALogger* uma_logger, | 218 const UMALogger* uma_logger, |
| 219 WriteTracker* tracker, | 219 WriteTracker* tracker, |
| 220 bool make_backup); | 220 bool make_backup); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 } | 323 } |
| 324 | 324 |
| 325 class IDBEnv : public ChromiumEnv { | 325 class IDBEnv : public ChromiumEnv { |
| 326 public: | 326 public: |
| 327 IDBEnv() : ChromiumEnv() { | 327 IDBEnv() : ChromiumEnv() { |
| 328 name_ = "LevelDBEnv.IDB"; | 328 name_ = "LevelDBEnv.IDB"; |
| 329 make_backup_ = true; | 329 make_backup_ = true; |
| 330 } | 330 } |
| 331 }; | 331 }; |
| 332 | 332 |
| 333 ::base::LazyInstance<IDBEnv>::Leaky idb_env = LAZY_INSTANCE_INITIALIZER; | 333 base::LazyInstance<IDBEnv>::Leaky idb_env = LAZY_INSTANCE_INITIALIZER; |
| 334 | 334 |
| 335 ::base::LazyInstance<ChromiumEnv>::Leaky default_env = | 335 base::LazyInstance<ChromiumEnv>::Leaky default_env = LAZY_INSTANCE_INITIALIZER; |
| 336 LAZY_INSTANCE_INITIALIZER; | |
| 337 | 336 |
| 338 } // unnamed namespace | 337 } // unnamed namespace |
| 339 | 338 |
| 340 const char* MethodIDToString(MethodID method) { | 339 const char* MethodIDToString(MethodID method) { |
| 341 switch (method) { | 340 switch (method) { |
| 342 case kSequentialFileRead: | 341 case kSequentialFileRead: |
| 343 return "SequentialFileRead"; | 342 return "SequentialFileRead"; |
| 344 case kSequentialFileSkip: | 343 case kSequentialFileSkip: |
| 345 return "SequentialFileSkip"; | 344 return "SequentialFileSkip"; |
| 346 case kRandomAccessFileRead: | 345 case kRandomAccessFileRead: |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 kMaxRetryTimeMillis(1000) { | 533 kMaxRetryTimeMillis(1000) { |
| 535 } | 534 } |
| 536 | 535 |
| 537 ChromiumEnv::~ChromiumEnv() { | 536 ChromiumEnv::~ChromiumEnv() { |
| 538 // In chromium, ChromiumEnv is leaked. It'd be nice to add NOTREACHED here to | 537 // In chromium, ChromiumEnv is leaked. It'd be nice to add NOTREACHED here to |
| 539 // ensure that behavior isn't accidentally changed, but there's an instance in | 538 // ensure that behavior isn't accidentally changed, but there's an instance in |
| 540 // a unit test that is deleted. | 539 // a unit test that is deleted. |
| 541 } | 540 } |
| 542 | 541 |
| 543 bool ChromiumEnv::FileExists(const std::string& fname) { | 542 bool ChromiumEnv::FileExists(const std::string& fname) { |
| 544 return ::base::PathExists(FilePath::FromUTF8Unsafe(fname)); | 543 return base::PathExists(FilePath::FromUTF8Unsafe(fname)); |
| 545 } | 544 } |
| 546 | 545 |
| 547 const char* ChromiumEnv::FileErrorString(::base::File::Error error) { | 546 const char* ChromiumEnv::FileErrorString(base::File::Error error) { |
| 548 switch (error) { | 547 switch (error) { |
| 549 case ::base::File::FILE_ERROR_FAILED: | 548 case base::File::FILE_ERROR_FAILED: |
| 550 return "No further details."; | 549 return "No further details."; |
| 551 case ::base::File::FILE_ERROR_IN_USE: | 550 case base::File::FILE_ERROR_IN_USE: |
| 552 return "File currently in use."; | 551 return "File currently in use."; |
| 553 case ::base::File::FILE_ERROR_EXISTS: | 552 case base::File::FILE_ERROR_EXISTS: |
| 554 return "File already exists."; | 553 return "File already exists."; |
| 555 case ::base::File::FILE_ERROR_NOT_FOUND: | 554 case base::File::FILE_ERROR_NOT_FOUND: |
| 556 return "File not found."; | 555 return "File not found."; |
| 557 case ::base::File::FILE_ERROR_ACCESS_DENIED: | 556 case base::File::FILE_ERROR_ACCESS_DENIED: |
| 558 return "Access denied."; | 557 return "Access denied."; |
| 559 case ::base::File::FILE_ERROR_TOO_MANY_OPENED: | 558 case base::File::FILE_ERROR_TOO_MANY_OPENED: |
| 560 return "Too many files open."; | 559 return "Too many files open."; |
| 561 case ::base::File::FILE_ERROR_NO_MEMORY: | 560 case base::File::FILE_ERROR_NO_MEMORY: |
| 562 return "Out of memory."; | 561 return "Out of memory."; |
| 563 case ::base::File::FILE_ERROR_NO_SPACE: | 562 case base::File::FILE_ERROR_NO_SPACE: |
| 564 return "No space left on drive."; | 563 return "No space left on drive."; |
| 565 case ::base::File::FILE_ERROR_NOT_A_DIRECTORY: | 564 case base::File::FILE_ERROR_NOT_A_DIRECTORY: |
| 566 return "Not a directory."; | 565 return "Not a directory."; |
| 567 case ::base::File::FILE_ERROR_INVALID_OPERATION: | 566 case base::File::FILE_ERROR_INVALID_OPERATION: |
| 568 return "Invalid operation."; | 567 return "Invalid operation."; |
| 569 case ::base::File::FILE_ERROR_SECURITY: | 568 case base::File::FILE_ERROR_SECURITY: |
| 570 return "Security error."; | 569 return "Security error."; |
| 571 case ::base::File::FILE_ERROR_ABORT: | 570 case base::File::FILE_ERROR_ABORT: |
| 572 return "File operation aborted."; | 571 return "File operation aborted."; |
| 573 case ::base::File::FILE_ERROR_NOT_A_FILE: | 572 case base::File::FILE_ERROR_NOT_A_FILE: |
| 574 return "The supplied path was not a file."; | 573 return "The supplied path was not a file."; |
| 575 case ::base::File::FILE_ERROR_NOT_EMPTY: | 574 case base::File::FILE_ERROR_NOT_EMPTY: |
| 576 return "The file was not empty."; | 575 return "The file was not empty."; |
| 577 case ::base::File::FILE_ERROR_INVALID_URL: | 576 case base::File::FILE_ERROR_INVALID_URL: |
| 578 return "Invalid URL."; | 577 return "Invalid URL."; |
| 579 case ::base::File::FILE_ERROR_IO: | 578 case base::File::FILE_ERROR_IO: |
| 580 return "OS or hardware error."; | 579 return "OS or hardware error."; |
| 581 case ::base::File::FILE_OK: | 580 case base::File::FILE_OK: |
| 582 return "OK."; | 581 return "OK."; |
| 583 case ::base::File::FILE_ERROR_MAX: | 582 case base::File::FILE_ERROR_MAX: |
| 584 NOTREACHED(); | 583 NOTREACHED(); |
| 585 } | 584 } |
| 586 NOTIMPLEMENTED(); | 585 NOTIMPLEMENTED(); |
| 587 return "Unknown error."; | 586 return "Unknown error."; |
| 588 } | 587 } |
| 589 | 588 |
| 590 FilePath ChromiumEnv::RestoreFromBackup(const FilePath& base_name) { | 589 FilePath ChromiumEnv::RestoreFromBackup(const FilePath& base_name) { |
| 591 FilePath table_name = base_name.AddExtension(table_extension); | 590 FilePath table_name = base_name.AddExtension(table_extension); |
| 592 bool result = base::CopyFile(base_name.AddExtension(backup_table_extension), | 591 bool result = base::CopyFile(base_name.AddExtension(backup_table_extension), |
| 593 table_name); | 592 table_name); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 if (make_backup_) | 648 if (make_backup_) |
| 650 RestoreIfNecessary(dir, result); | 649 RestoreIfNecessary(dir, result); |
| 651 | 650 |
| 652 return Status::OK(); | 651 return Status::OK(); |
| 653 } | 652 } |
| 654 | 653 |
| 655 Status ChromiumEnv::DeleteFile(const std::string& fname) { | 654 Status ChromiumEnv::DeleteFile(const std::string& fname) { |
| 656 Status result; | 655 Status result; |
| 657 FilePath fname_filepath = FilePath::FromUTF8Unsafe(fname); | 656 FilePath fname_filepath = FilePath::FromUTF8Unsafe(fname); |
| 658 // TODO(jorlow): Should we assert this is a file? | 657 // TODO(jorlow): Should we assert this is a file? |
| 659 if (!::base::DeleteFile(fname_filepath, false)) { | 658 if (!base::DeleteFile(fname_filepath, false)) { |
| 660 result = MakeIOError(fname, "Could not delete file.", kDeleteFile); | 659 result = MakeIOError(fname, "Could not delete file.", kDeleteFile); |
| 661 RecordErrorAt(kDeleteFile); | 660 RecordErrorAt(kDeleteFile); |
| 662 } | 661 } |
| 663 if (make_backup_ && fname_filepath.MatchesExtension(table_extension)) { | 662 if (make_backup_ && fname_filepath.MatchesExtension(table_extension)) { |
| 664 base::DeleteFile(fname_filepath.ReplaceExtension(backup_table_extension), | 663 base::DeleteFile(fname_filepath.ReplaceExtension(backup_table_extension), |
| 665 false); | 664 false); |
| 666 } | 665 } |
| 667 return result; | 666 return result; |
| 668 } | 667 } |
| 669 | 668 |
| 670 Status ChromiumEnv::CreateDir(const std::string& name) { | 669 Status ChromiumEnv::CreateDir(const std::string& name) { |
| 671 Status result; | 670 Status result; |
| 672 base::File::Error error = base::File::FILE_OK; | 671 base::File::Error error = base::File::FILE_OK; |
| 673 Retrier retrier(kCreateDir, this); | 672 Retrier retrier(kCreateDir, this); |
| 674 do { | 673 do { |
| 675 if (base::CreateDirectoryAndGetError(FilePath::FromUTF8Unsafe(name), | 674 if (base::CreateDirectoryAndGetError(FilePath::FromUTF8Unsafe(name), |
| 676 &error)) | 675 &error)) |
| 677 return result; | 676 return result; |
| 678 } while (retrier.ShouldKeepTrying(error)); | 677 } while (retrier.ShouldKeepTrying(error)); |
| 679 result = MakeIOError(name, "Could not create directory.", kCreateDir, error); | 678 result = MakeIOError(name, "Could not create directory.", kCreateDir, error); |
| 680 RecordOSError(kCreateDir, error); | 679 RecordOSError(kCreateDir, error); |
| 681 return result; | 680 return result; |
| 682 } | 681 } |
| 683 | 682 |
| 684 Status ChromiumEnv::DeleteDir(const std::string& name) { | 683 Status ChromiumEnv::DeleteDir(const std::string& name) { |
| 685 Status result; | 684 Status result; |
| 686 // TODO(jorlow): Should we assert this is a directory? | 685 // TODO(jorlow): Should we assert this is a directory? |
| 687 if (!::base::DeleteFile(FilePath::FromUTF8Unsafe(name), false)) { | 686 if (!base::DeleteFile(FilePath::FromUTF8Unsafe(name), false)) { |
| 688 result = MakeIOError(name, "Could not delete directory.", kDeleteDir); | 687 result = MakeIOError(name, "Could not delete directory.", kDeleteDir); |
| 689 RecordErrorAt(kDeleteDir); | 688 RecordErrorAt(kDeleteDir); |
| 690 } | 689 } |
| 691 return result; | 690 return result; |
| 692 } | 691 } |
| 693 | 692 |
| 694 Status ChromiumEnv::GetFileSize(const std::string& fname, uint64_t* size) { | 693 Status ChromiumEnv::GetFileSize(const std::string& fname, uint64_t* size) { |
| 695 Status s; | 694 Status s; |
| 696 int64_t signed_size; | 695 int64_t signed_size; |
| 697 if (!::base::GetFileSize(FilePath::FromUTF8Unsafe(fname), &signed_size)) { | 696 if (!base::GetFileSize(FilePath::FromUTF8Unsafe(fname), &signed_size)) { |
| 698 *size = 0; | 697 *size = 0; |
| 699 s = MakeIOError(fname, "Could not determine file size.", kGetFileSize); | 698 s = MakeIOError(fname, "Could not determine file size.", kGetFileSize); |
| 700 RecordErrorAt(kGetFileSize); | 699 RecordErrorAt(kGetFileSize); |
| 701 } else { | 700 } else { |
| 702 *size = static_cast<uint64_t>(signed_size); | 701 *size = static_cast<uint64_t>(signed_size); |
| 703 } | 702 } |
| 704 return s; | 703 return s; |
| 705 } | 704 } |
| 706 | 705 |
| 707 Status ChromiumEnv::RenameFile(const std::string& src, const std::string& dst) { | 706 Status ChromiumEnv::RenameFile(const std::string& src, const std::string& dst) { |
| 708 Status result; | 707 Status result; |
| 709 FilePath src_file_path = FilePath::FromUTF8Unsafe(src); | 708 FilePath src_file_path = FilePath::FromUTF8Unsafe(src); |
| 710 if (!::base::PathExists(src_file_path)) | 709 if (!base::PathExists(src_file_path)) |
| 711 return result; | 710 return result; |
| 712 FilePath destination = FilePath::FromUTF8Unsafe(dst); | 711 FilePath destination = FilePath::FromUTF8Unsafe(dst); |
| 713 | 712 |
| 714 Retrier retrier(kRenameFile, this); | 713 Retrier retrier(kRenameFile, this); |
| 715 base::File::Error error = base::File::FILE_OK; | 714 base::File::Error error = base::File::FILE_OK; |
| 716 do { | 715 do { |
| 717 if (base::ReplaceFile(src_file_path, destination, &error)) | 716 if (base::ReplaceFile(src_file_path, destination, &error)) |
| 718 return result; | 717 return result; |
| 719 } while (retrier.ShouldKeepTrying(error)); | 718 } while (retrier.ShouldKeepTrying(error)); |
| 720 | 719 |
| 721 DCHECK(error != base::File::FILE_OK); | 720 DCHECK(error != base::File::FILE_OK); |
| 722 RecordOSError(kRenameFile, error); | 721 RecordOSError(kRenameFile, error); |
| 723 char buf[100]; | 722 char buf[100]; |
| 724 snprintf(buf, | 723 snprintf(buf, |
| 725 sizeof(buf), | 724 sizeof(buf), |
| 726 "Could not rename file: %s", | 725 "Could not rename file: %s", |
| 727 FileErrorString(error)); | 726 FileErrorString(error)); |
| 728 return MakeIOError(src, buf, kRenameFile, error); | 727 return MakeIOError(src, buf, kRenameFile, error); |
| 729 } | 728 } |
| 730 | 729 |
| 731 Status ChromiumEnv::LockFile(const std::string& fname, FileLock** lock) { | 730 Status ChromiumEnv::LockFile(const std::string& fname, FileLock** lock) { |
| 732 *lock = NULL; | 731 *lock = NULL; |
| 733 Status result; | 732 Status result; |
| 734 int flags = ::base::File::FLAG_OPEN_ALWAYS | | 733 int flags = base::File::FLAG_OPEN_ALWAYS | |
| 735 ::base::File::FLAG_READ | | 734 base::File::FLAG_READ | |
| 736 ::base::File::FLAG_WRITE; | 735 base::File::FLAG_WRITE; |
| 737 ::base::File::Error error_code; | 736 base::File::Error error_code; |
| 738 ::base::File file; | 737 base::File file; |
| 739 Retrier retrier(kLockFile, this); | 738 Retrier retrier(kLockFile, this); |
| 740 do { | 739 do { |
| 741 file.Initialize(FilePath::FromUTF8Unsafe(fname), flags); | 740 file.Initialize(FilePath::FromUTF8Unsafe(fname), flags); |
| 742 if (!file.IsValid()) | 741 if (!file.IsValid()) |
| 743 error_code = file.error_details(); | 742 error_code = file.error_details(); |
| 744 } while (!file.IsValid() && retrier.ShouldKeepTrying(error_code)); | 743 } while (!file.IsValid() && retrier.ShouldKeepTrying(error_code)); |
| 745 | 744 |
| 746 if (!file.IsValid()) { | 745 if (!file.IsValid()) { |
| 747 if (error_code == ::base::File::FILE_ERROR_NOT_FOUND) { | 746 if (error_code == base::File::FILE_ERROR_NOT_FOUND) { |
| 748 FilePath parent = FilePath::FromUTF8Unsafe(fname).DirName(); | 747 FilePath parent = FilePath::FromUTF8Unsafe(fname).DirName(); |
| 749 FilePath last_parent; | 748 FilePath last_parent; |
| 750 int num_missing_ancestors = 0; | 749 int num_missing_ancestors = 0; |
| 751 do { | 750 do { |
| 752 if (base::DirectoryExists(parent)) | 751 if (base::DirectoryExists(parent)) |
| 753 break; | 752 break; |
| 754 ++num_missing_ancestors; | 753 ++num_missing_ancestors; |
| 755 last_parent = parent; | 754 last_parent = parent; |
| 756 parent = parent.DirName(); | 755 parent = parent.DirName(); |
| 757 } while (parent != last_parent); | 756 } while (parent != last_parent); |
| 758 RecordLockFileAncestors(num_missing_ancestors); | 757 RecordLockFileAncestors(num_missing_ancestors); |
| 759 } | 758 } |
| 760 | 759 |
| 761 result = MakeIOError(fname, FileErrorString(error_code), kLockFile, | 760 result = MakeIOError(fname, FileErrorString(error_code), kLockFile, |
| 762 error_code); | 761 error_code); |
| 763 RecordOSError(kLockFile, error_code); | 762 RecordOSError(kLockFile, error_code); |
| 764 return result; | 763 return result; |
| 765 } | 764 } |
| 766 | 765 |
| 767 if (!locks_.Insert(fname)) { | 766 if (!locks_.Insert(fname)) { |
| 768 result = MakeIOError(fname, "Lock file already locked.", kLockFile); | 767 result = MakeIOError(fname, "Lock file already locked.", kLockFile); |
| 769 return result; | 768 return result; |
| 770 } | 769 } |
| 771 | 770 |
| 772 Retrier lock_retrier = Retrier(kLockFile, this); | 771 Retrier lock_retrier = Retrier(kLockFile, this); |
| 773 do { | 772 do { |
| 774 error_code = file.Lock(); | 773 error_code = file.Lock(); |
| 775 } while (error_code != ::base::File::FILE_OK && | 774 } while (error_code != base::File::FILE_OK && |
| 776 retrier.ShouldKeepTrying(error_code)); | 775 retrier.ShouldKeepTrying(error_code)); |
| 777 | 776 |
| 778 if (error_code != ::base::File::FILE_OK) { | 777 if (error_code != base::File::FILE_OK) { |
| 779 locks_.Remove(fname); | 778 locks_.Remove(fname); |
| 780 result = MakeIOError(fname, FileErrorString(error_code), kLockFile, | 779 result = MakeIOError(fname, FileErrorString(error_code), kLockFile, |
| 781 error_code); | 780 error_code); |
| 782 RecordOSError(kLockFile, error_code); | 781 RecordOSError(kLockFile, error_code); |
| 783 return result; | 782 return result; |
| 784 } | 783 } |
| 785 | 784 |
| 786 ChromiumFileLock* my_lock = new ChromiumFileLock; | 785 ChromiumFileLock* my_lock = new ChromiumFileLock; |
| 787 my_lock->file_ = file.Pass(); | 786 my_lock->file_ = file.Pass(); |
| 788 my_lock->name_ = fname; | 787 my_lock->name_ = fname; |
| 789 *lock = my_lock; | 788 *lock = my_lock; |
| 790 return result; | 789 return result; |
| 791 } | 790 } |
| 792 | 791 |
| 793 Status ChromiumEnv::UnlockFile(FileLock* lock) { | 792 Status ChromiumEnv::UnlockFile(FileLock* lock) { |
| 794 ChromiumFileLock* my_lock = reinterpret_cast<ChromiumFileLock*>(lock); | 793 ChromiumFileLock* my_lock = reinterpret_cast<ChromiumFileLock*>(lock); |
| 795 Status result; | 794 Status result; |
| 796 | 795 |
| 797 ::base::File::Error error_code = my_lock->file_.Unlock(); | 796 base::File::Error error_code = my_lock->file_.Unlock(); |
| 798 if (error_code != ::base::File::FILE_OK) { | 797 if (error_code != base::File::FILE_OK) { |
| 799 result = | 798 result = |
| 800 MakeIOError(my_lock->name_, "Could not unlock lock file.", kUnlockFile); | 799 MakeIOError(my_lock->name_, "Could not unlock lock file.", kUnlockFile); |
| 801 RecordOSError(kUnlockFile, error_code); | 800 RecordOSError(kUnlockFile, error_code); |
| 802 } | 801 } |
| 803 bool removed = locks_.Remove(my_lock->name_); | 802 bool removed = locks_.Remove(my_lock->name_); |
| 804 DCHECK(removed); | 803 DCHECK(removed); |
| 805 delete my_lock; | 804 delete my_lock; |
| 806 return result; | 805 return result; |
| 807 } | 806 } |
| 808 | 807 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 859 GetMaxFDHistogram(type)->Add(base::GetMaxFds()); | 858 GetMaxFDHistogram(type)->Add(base::GetMaxFds()); |
| 860 #elif defined(OS_WIN) | 859 #elif defined(OS_WIN) |
| 861 // Windows is only limited by available memory | 860 // Windows is only limited by available memory |
| 862 #else | 861 #else |
| 863 #error "Need to determine limit to open files for this OS" | 862 #error "Need to determine limit to open files for this OS" |
| 864 #endif | 863 #endif |
| 865 } | 864 } |
| 866 | 865 |
| 867 Status ChromiumEnv::NewRandomAccessFile(const std::string& fname, | 866 Status ChromiumEnv::NewRandomAccessFile(const std::string& fname, |
| 868 leveldb::RandomAccessFile** result) { | 867 leveldb::RandomAccessFile** result) { |
| 869 int flags = ::base::File::FLAG_READ | ::base::File::FLAG_OPEN; | 868 int flags = base::File::FLAG_READ | base::File::FLAG_OPEN; |
| 870 ::base::File file(FilePath::FromUTF8Unsafe(fname), flags); | 869 base::File file(FilePath::FromUTF8Unsafe(fname), flags); |
| 871 if (file.IsValid()) { | 870 if (file.IsValid()) { |
| 872 *result = new ChromiumRandomAccessFile(fname, file.Pass(), this); | 871 *result = new ChromiumRandomAccessFile(fname, file.Pass(), this); |
| 873 RecordOpenFilesLimit("Success"); | 872 RecordOpenFilesLimit("Success"); |
| 874 return Status::OK(); | 873 return Status::OK(); |
| 875 } | 874 } |
| 876 ::base::File::Error error_code = file.error_details(); | 875 base::File::Error error_code = file.error_details(); |
| 877 if (error_code == ::base::File::FILE_ERROR_TOO_MANY_OPENED) | 876 if (error_code == base::File::FILE_ERROR_TOO_MANY_OPENED) |
| 878 RecordOpenFilesLimit("TooManyOpened"); | 877 RecordOpenFilesLimit("TooManyOpened"); |
| 879 else | 878 else |
| 880 RecordOpenFilesLimit("OtherError"); | 879 RecordOpenFilesLimit("OtherError"); |
| 881 *result = NULL; | 880 *result = NULL; |
| 882 RecordOSError(kNewRandomAccessFile, error_code); | 881 RecordOSError(kNewRandomAccessFile, error_code); |
| 883 return MakeIOError(fname, FileErrorString(error_code), kNewRandomAccessFile, | 882 return MakeIOError(fname, FileErrorString(error_code), kNewRandomAccessFile, |
| 884 error_code); | 883 error_code); |
| 885 } | 884 } |
| 886 | 885 |
| 887 Status ChromiumEnv::NewWritableFile(const std::string& fname, | 886 Status ChromiumEnv::NewWritableFile(const std::string& fname, |
| 888 leveldb::WritableFile** result) { | 887 leveldb::WritableFile** result) { |
| 889 *result = NULL; | 888 *result = NULL; |
| 890 FilePath path = FilePath::FromUTF8Unsafe(fname); | 889 FilePath path = FilePath::FromUTF8Unsafe(fname); |
| 891 scoped_ptr<base::File> f(new base::File( | 890 scoped_ptr<base::File> f(new base::File( |
| 892 path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE)); | 891 path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE)); |
| 893 if (!f->IsValid()) { | 892 if (!f->IsValid()) { |
| 894 RecordErrorAt(kNewWritableFile); | 893 RecordErrorAt(kNewWritableFile); |
| 895 return MakeIOError(fname, "Unable to create writable file", | 894 return MakeIOError(fname, "Unable to create writable file", |
| 896 kNewWritableFile, f->error_details()); | 895 kNewWritableFile, f->error_details()); |
| 897 } else { | 896 } else { |
| 898 *result = | 897 *result = |
| 899 new ChromiumWritableFile(fname, f.release(), this, this, make_backup_); | 898 new ChromiumWritableFile(fname, f.release(), this, this, make_backup_); |
| 900 return Status::OK(); | 899 return Status::OK(); |
| 901 } | 900 } |
| 902 } | 901 } |
| 903 | 902 |
| 904 uint64_t ChromiumEnv::NowMicros() { | 903 uint64_t ChromiumEnv::NowMicros() { |
| 905 return ::base::TimeTicks::Now().ToInternalValue(); | 904 return base::TimeTicks::Now().ToInternalValue(); |
| 906 } | 905 } |
| 907 | 906 |
| 908 void ChromiumEnv::SleepForMicroseconds(int micros) { | 907 void ChromiumEnv::SleepForMicroseconds(int micros) { |
| 909 // Round up to the next millisecond. | 908 // Round up to the next millisecond. |
| 910 ::base::PlatformThread::Sleep(::base::TimeDelta::FromMicroseconds(micros)); | 909 base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(micros)); |
| 911 } | 910 } |
| 912 | 911 |
| 913 void ChromiumEnv::RecordErrorAt(MethodID method) const { | 912 void ChromiumEnv::RecordErrorAt(MethodID method) const { |
| 914 GetMethodIOErrorHistogram()->Add(method); | 913 GetMethodIOErrorHistogram()->Add(method); |
| 915 } | 914 } |
| 916 | 915 |
| 917 void ChromiumEnv::RecordLockFileAncestors(int num_missing_ancestors) const { | 916 void ChromiumEnv::RecordLockFileAncestors(int num_missing_ancestors) const { |
| 918 GetLockFileAncestorHistogram()->Add(num_missing_ancestors); | 917 GetLockFileAncestorHistogram()->Add(num_missing_ancestors); |
| 919 } | 918 } |
| 920 | 919 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 | 988 |
| 990 base::HistogramBase* ChromiumEnv::GetRecoveredFromErrorHistogram( | 989 base::HistogramBase* ChromiumEnv::GetRecoveredFromErrorHistogram( |
| 991 MethodID method) const { | 990 MethodID method) const { |
| 992 std::string uma_name(name_); | 991 std::string uma_name(name_); |
| 993 uma_name.append(".RetryRecoveredFromErrorIn") | 992 uma_name.append(".RetryRecoveredFromErrorIn") |
| 994 .append(MethodIDToString(method)); | 993 .append(MethodIDToString(method)); |
| 995 return base::LinearHistogram::FactoryGet(uma_name, 1, kNumEntries, | 994 return base::LinearHistogram::FactoryGet(uma_name, 1, kNumEntries, |
| 996 kNumEntries + 1, base::Histogram::kUmaTargetedHistogramFlag); | 995 kNumEntries + 1, base::Histogram::kUmaTargetedHistogramFlag); |
| 997 } | 996 } |
| 998 | 997 |
| 999 class Thread : public ::base::PlatformThread::Delegate { | 998 class Thread : public base::PlatformThread::Delegate { |
| 1000 public: | 999 public: |
| 1001 Thread(void (*function)(void* arg), void* arg) | 1000 Thread(void (*function)(void* arg), void* arg) |
| 1002 : function_(function), arg_(arg) { | 1001 : function_(function), arg_(arg) { |
| 1003 ::base::PlatformThreadHandle handle; | 1002 base::PlatformThreadHandle handle; |
| 1004 bool success = ::base::PlatformThread::Create(0, this, &handle); | 1003 bool success = base::PlatformThread::Create(0, this, &handle); |
| 1005 DCHECK(success); | 1004 DCHECK(success); |
| 1006 } | 1005 } |
| 1007 virtual ~Thread() {} | 1006 virtual ~Thread() {} |
| 1008 void ThreadMain() override { | 1007 void ThreadMain() override { |
| 1009 (*function_)(arg_); | 1008 (*function_)(arg_); |
| 1010 delete this; | 1009 delete this; |
| 1011 } | 1010 } |
| 1012 | 1011 |
| 1013 private: | 1012 private: |
| 1014 void (*function_)(void* arg); | 1013 void (*function_)(void* arg); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1087 | 1086 |
| 1088 Env* IDBEnv() { | 1087 Env* IDBEnv() { |
| 1089 return leveldb_env::idb_env.Pointer(); | 1088 return leveldb_env::idb_env.Pointer(); |
| 1090 } | 1089 } |
| 1091 | 1090 |
| 1092 Env* Env::Default() { | 1091 Env* Env::Default() { |
| 1093 return leveldb_env::default_env.Pointer(); | 1092 return leveldb_env::default_env.Pointer(); |
| 1094 } | 1093 } |
| 1095 | 1094 |
| 1096 } // namespace leveldb | 1095 } // namespace leveldb |
| OLD | NEW |