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 |