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

Side by Side Diff: third_party/leveldatabase/env_chromium.cc

Issue 710373002: LevelDB: Using base::File for all file I/O (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: iterator -> range based for loop + GetDirectoryEntries cleanup Created 6 years, 1 month 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
OLDNEW
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_WIN) 7 #if defined(OS_POSIX)
8 #include <io.h> 8 #include <dirent.h>
9 #include <sys/types.h>
9 #endif 10 #endif
10 11
11 #include "base/debug/trace_event.h" 12 #include "base/debug/trace_event.h"
13 #include "base/files/file_enumerator.h"
jsbell 2014/11/14 00:12:33 No longer needed?
cmumford 2014/11/14 22:43:57 Done.
12 #include "base/files/file_util.h" 14 #include "base/files/file_util.h"
13 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
16 #include "base/memory/shared_memory.h"
14 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/process/process_metrics.h"
15 #include "base/stl_util.h" 19 #include "base/stl_util.h"
16 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
17 #include "third_party/leveldatabase/env_chromium_stdio.h" 21 #include "third_party/leveldatabase/chromium_logger.h"
18 #include "third_party/re2/re2/re2.h" 22 #include "third_party/re2/re2/re2.h"
19 23
20 #if defined(OS_WIN)
21 #include "base/command_line.h"
22 #include "base/win/win_util.h"
23 #include "third_party/leveldatabase/env_chromium_win.h"
24 #endif
25
26 using leveldb::FileLock; 24 using leveldb::FileLock;
27 using leveldb::Slice; 25 using leveldb::Slice;
28 using leveldb::Status; 26 using leveldb::Status;
29 27
30 namespace leveldb_env { 28 namespace leveldb_env {
31 29
32 namespace { 30 namespace {
33 31
34 const base::FilePath::CharType backup_table_extension[] = 32 const base::FilePath::CharType backup_table_extension[] =
35 FILE_PATH_LITERAL(".bak"); 33 FILE_PATH_LITERAL(".bak");
36 const base::FilePath::CharType table_extension[] = FILE_PATH_LITERAL(".ldb"); 34 const base::FilePath::CharType table_extension[] = FILE_PATH_LITERAL(".ldb");
37 35
38 static const base::FilePath::CharType kLevelDBTestDirectoryPrefix[] 36 static const base::FilePath::CharType kLevelDBTestDirectoryPrefix[]
39 = FILE_PATH_LITERAL("leveldb-test-"); 37 = FILE_PATH_LITERAL("leveldb-test-");
40 38
39 static base::File::Error LastFileError() {
40 #if defined(OS_WIN)
41 return base::File::OSErrorToFileError(GetLastError());
42 #else
43 return base::File::OSErrorToFileError(errno);
44 #endif
45 }
46
47 static base::File::Error GetDirectoryEntries(
jsbell 2014/11/14 00:12:34 Add a comment with the rationale for using this in
cmumford 2014/11/14 22:43:57 Done.
48 const base::FilePath& dir_param,
49 std::vector<base::FilePath>* result) {
50 result->clear();
51 #if defined(OS_WIN)
52 base::FilePath dir_filepath = dir_param.Append(FILE_PATH_LITERAL("*"));
53 WIN32_FIND_DATA find_data;
54 HANDLE find_handle = FindFirstFile(dir_filepath.value().c_str(), &find_data);
55 if (find_handle == INVALID_HANDLE_VALUE) {
56 DWORD last_error = GetLastError();
57 if (last_error == ERROR_FILE_NOT_FOUND)
58 return base::File::FILE_OK;
59 return base::File::OSErrorToFileError(last_error);
60 }
61 do {
62 base::FilePath filepath(find_data.cFileName);
63 base::FilePath::StringType basename = filepath.BaseName().value();
64 if (basename == FILE_PATH_LITERAL(".") ||
65 basename == FILE_PATH_LITERAL(".."))
66 continue;
67 result->push_back(filepath.BaseName());
68 } while (FindNextFile(find_handle, &find_data));
69 DWORD last_error = GetLastError();
70 base::File::Error return_value = base::File::FILE_OK;
71 if (last_error != ERROR_NO_MORE_FILES)
72 return_value = base::File::OSErrorToFileError(last_error);
73 FindClose(find_handle);
74 return return_value;
75 #else
76 const std::string dir_string = FilePathToString(dir_param);
77 DIR* dir = opendir(dir_string.c_str());
78 if (!dir)
79 return base::File::OSErrorToFileError(errno);
80 struct dirent dent_buf;
81 struct dirent* dent;
82 int readdir_result;
83 while ((readdir_result = readdir_r(dir, &dent_buf, &dent)) == 0 && dent) {
84 if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0)
85 continue;
86 result->push_back(ChromiumEnv::CreateFilePath(dent->d_name));
87 }
88 int saved_errno = errno;
89 closedir(dir);
90 if (readdir_result != 0)
91 return base::File::OSErrorToFileError(saved_errno);
92 return base::File::FILE_OK;
93 #endif
94 }
95
41 class ChromiumFileLock : public FileLock { 96 class ChromiumFileLock : public FileLock {
42 public: 97 public:
43 ::base::File file_; 98 ::base::File file_;
jsbell 2014/11/14 00:12:33 Bit of a tangent but... what's up with ::base vs.
cmumford 2014/11/14 22:43:57 I have another CL that will follow up this one wit
44 std::string name_; 99 std::string name_;
45 }; 100 };
46 101
47 class Retrier { 102 class Retrier {
48 public: 103 public:
49 Retrier(MethodID method, RetrierProvider* provider) 104 Retrier(MethodID method, RetrierProvider* provider)
50 : start_(base::TimeTicks::Now()), 105 : start_(base::TimeTicks::Now()),
51 limit_(start_ + base::TimeDelta::FromMilliseconds( 106 limit_(start_ + base::TimeDelta::FromMilliseconds(
52 provider->MaxRetryTimeMillis())), 107 provider->MaxRetryTimeMillis())),
53 last_(start_), 108 last_(start_),
(...skipping 27 matching lines...) Expand all
81 base::TimeTicks start_; 136 base::TimeTicks start_;
82 base::TimeTicks limit_; 137 base::TimeTicks limit_;
83 base::TimeTicks last_; 138 base::TimeTicks last_;
84 base::TimeDelta time_to_sleep_; 139 base::TimeDelta time_to_sleep_;
85 bool success_; 140 bool success_;
86 MethodID method_; 141 MethodID method_;
87 base::File::Error last_error_; 142 base::File::Error last_error_;
88 RetrierProvider* provider_; 143 RetrierProvider* provider_;
89 }; 144 };
90 145
91 class IDBEnvStdio : public ChromiumEnvStdio { 146 class ChromiumSequentialFile : public leveldb::SequentialFile {
92 public: 147 public:
93 IDBEnvStdio() : ChromiumEnvStdio() { 148 ChromiumSequentialFile(const std::string& fname,
149 base::File* f,
150 const UMALogger* uma_logger)
151 : filename_(fname), file_(f), uma_logger_(uma_logger) {}
152 virtual ~ChromiumSequentialFile() {}
153
154 Status Read(size_t n, Slice* result, char* scratch) override {
155 int bytes_read = file_->ReadAtCurrentPos(scratch, n);
156 if (bytes_read == -1) {
157 base::File::Error error = LastFileError();
158 uma_logger_->RecordErrorAt(kSequentialFileRead);
159 return MakeIOError(filename_, base::File::ErrorToString(error),
160 kSequentialFileRead, error);
161 } else {
162 *result = Slice(scratch, bytes_read);
163 return Status::OK();
164 }
165 }
166
167 Status Skip(uint64_t n) override {
168 if (file_->Seek(base::File::FROM_CURRENT, n) == -1) {
169 base::File::Error error = LastFileError();
170 uma_logger_->RecordErrorAt(kSequentialFileSkip);
171 return MakeIOError(filename_, base::File::ErrorToString(error),
172 kSequentialFileSkip, error);
173 } else {
174 return Status::OK();
175 }
176 }
177
178 private:
179 std::string filename_;
180 scoped_ptr<base::File> file_;
181 const UMALogger* uma_logger_;
182 };
183
184 class ChromiumRandomAccessFile : public leveldb::RandomAccessFile {
185 public:
186 ChromiumRandomAccessFile(const std::string& fname,
187 ::base::File file,
188 const UMALogger* uma_logger)
189 : filename_(fname), file_(file.Pass()), uma_logger_(uma_logger) {}
190 virtual ~ChromiumRandomAccessFile() {}
191
192 Status Read(uint64_t offset,
193 size_t n,
194 Slice* result,
195 char* scratch) const override {
196 Status s;
197 int r = file_.Read(offset, scratch, n);
198 *result = Slice(scratch, (r < 0) ? 0 : r);
199 if (r < 0) {
200 // An error: return a non-ok status
201 s = MakeIOError(filename_, "Could not perform read",
202 kRandomAccessFileRead);
203 uma_logger_->RecordErrorAt(kRandomAccessFileRead);
204 }
205 return s;
206 }
207
208 private:
209 std::string filename_;
210 mutable ::base::File file_;
211 const UMALogger* uma_logger_;
212 };
213
214 class ChromiumWritableFile : public leveldb::WritableFile {
215 public:
216 ChromiumWritableFile(const std::string& fname,
217 base::File* f,
218 const UMALogger* uma_logger,
219 WriteTracker* tracker,
220 bool make_backup);
221 virtual ~ChromiumWritableFile() {}
222 leveldb::Status Append(const leveldb::Slice& data) override;
223 leveldb::Status Close() override;
224 leveldb::Status Flush() override;
225 leveldb::Status Sync() override;
226
227 private:
228 enum Type { kManifest, kTable, kOther };
229 leveldb::Status SyncParent();
230
231 std::string filename_;
232 scoped_ptr<base::File> file_;
233 const UMALogger* uma_logger_;
234 WriteTracker* tracker_;
235 Type file_type_;
236 std::string parent_dir_;
237 bool make_backup_;
238 };
239
240 ChromiumWritableFile::ChromiumWritableFile(const std::string& fname,
241 base::File* f,
242 const UMALogger* uma_logger,
243 WriteTracker* tracker,
244 bool make_backup)
245 : filename_(fname),
246 file_(f),
247 uma_logger_(uma_logger),
248 tracker_(tracker),
249 file_type_(kOther),
250 make_backup_(make_backup) {
251 base::FilePath path = base::FilePath::FromUTF8Unsafe(fname);
252 if (FilePathToString(path.BaseName()).find("MANIFEST") == 0)
253 file_type_ = kManifest;
254 else if (ChromiumEnv::HasTableExtension(path))
255 file_type_ = kTable;
256 if (file_type_ != kManifest)
257 tracker_->DidCreateNewFile(filename_);
258 parent_dir_ = FilePathToString(ChromiumEnv::CreateFilePath(fname).DirName());
259 }
260
261 Status ChromiumWritableFile::SyncParent() {
262 TRACE_EVENT0("leveldb", "SyncParent");
263 #if defined(OS_POSIX)
264 base::FilePath path = base::FilePath::FromUTF8Unsafe(parent_dir_);
265 base::File f(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
266 if (!f.IsValid()) {
267 return MakeIOError(parent_dir_, "Unable to open directory", kSyncParent,
268 f.error_details());
269 }
270 if (!f.Flush()) {
271 base::File::Error error = LastFileError();
272 return MakeIOError(parent_dir_, base::File::ErrorToString(error),
273 kSyncParent, error);
274 }
275 #endif
276 return Status::OK();
277 }
278
279 Status ChromiumWritableFile::Append(const Slice& data) {
280 if (file_type_ == kManifest && tracker_->DoesDirNeedSync(filename_)) {
281 Status s = SyncParent();
282 if (!s.ok())
283 return s;
284 tracker_->DidSyncDir(filename_);
285 }
286
287 int bytes_written = file_->WriteAtCurrentPos(data.data(), data.size());
288 if (bytes_written != data.size()) {
289 base::File::Error error = LastFileError();
290 uma_logger_->RecordOSError(kWritableFileAppend, error);
291 return MakeIOError(filename_, base::File::ErrorToString(error),
292 kWritableFileAppend, error);
293 }
294
295 return Status::OK();
296 }
297
298 Status ChromiumWritableFile::Close() {
299 file_->Close();
300 return Status::OK();
301 }
302
303 Status ChromiumWritableFile::Flush() {
304 // base::File doesn't do buffered I/O (i.e. POSIX FILE streams) so nothing to
305 // flush.
306 return Status::OK();
307 }
308
309 Status ChromiumWritableFile::Sync() {
310 TRACE_EVENT0("leveldb", "WritableFile::Sync");
311
312 if (!file_->Flush()) {
313 base::File::Error error = LastFileError();
314 uma_logger_->RecordErrorAt(kWritableFileSync);
315 return MakeIOError(filename_, base::File::ErrorToString(error),
316 kWritableFileSync, error);
317 }
318
319 if (make_backup_ && file_type_ == kTable)
320 uma_logger_->RecordBackupResult(ChromiumEnv::MakeBackup(filename_));
321
322 return Status::OK();
323 }
324
325 class IDBEnv : public ChromiumEnv {
326 public:
327 IDBEnv() : ChromiumEnv() {
94 name_ = "LevelDBEnv.IDB"; 328 name_ = "LevelDBEnv.IDB";
95 make_backup_ = true; 329 make_backup_ = true;
96 } 330 }
97 }; 331 };
98 332
99 #if defined(OS_WIN) 333 ::base::LazyInstance<IDBEnv>::Leaky idb_env = LAZY_INSTANCE_INITIALIZER;
100 class IDBEnvWin : public ChromiumEnvWin {
101 public:
102 IDBEnvWin() : ChromiumEnvWin() {
103 name_ = "LevelDBEnv.IDB";
104 make_backup_ = true;
105 }
106 };
107 #endif
108 334
109 #if defined(OS_WIN) 335 ::base::LazyInstance<ChromiumEnv>::Leaky default_env =
110 ::base::LazyInstance<IDBEnvWin>::Leaky idb_env =
111 LAZY_INSTANCE_INITIALIZER;
112 #else
113 ::base::LazyInstance<IDBEnvStdio>::Leaky idb_env =
114 LAZY_INSTANCE_INITIALIZER;
115 #endif
116
117 ::base::LazyInstance<ChromiumEnvStdio>::Leaky default_env =
118 LAZY_INSTANCE_INITIALIZER; 336 LAZY_INSTANCE_INITIALIZER;
119 337
120 } // unnamed namespace 338 } // unnamed namespace
121 339
122 const char* MethodIDToString(MethodID method) { 340 const char* MethodIDToString(MethodID method) {
123 switch (method) { 341 switch (method) {
124 case kSequentialFileRead: 342 case kSequentialFileRead:
125 return "SequentialFileRead"; 343 return "SequentialFileRead";
126 case kSequentialFileSkip: 344 case kSequentialFileSkip:
127 return "SequentialFileSkip"; 345 return "SequentialFileSkip";
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 return "GetChildren"; 383 return "GetChildren";
166 case kNumEntries: 384 case kNumEntries:
167 NOTREACHED(); 385 NOTREACHED();
168 return "kNumEntries"; 386 return "kNumEntries";
169 } 387 }
170 NOTREACHED(); 388 NOTREACHED();
171 return "Unknown"; 389 return "Unknown";
172 } 390 }
173 391
174 Status MakeIOError(Slice filename, 392 Status MakeIOError(Slice filename,
175 const char* message, 393 const std::string& message,
176 MethodID method, 394 MethodID method,
177 int saved_errno) { 395 base::File::Error error) {
396 DCHECK_LT(error, 0);
178 char buf[512]; 397 char buf[512];
179 snprintf(buf, 398 snprintf(buf, sizeof(buf), "%s (ChromeMethodPFE: %d::%s::%d)",
180 sizeof(buf), 399 message.c_str(), method, MethodIDToString(method), -error);
181 "%s (ChromeMethodErrno: %d::%s::%d)",
182 message,
183 method,
184 MethodIDToString(method),
185 saved_errno);
186 return Status::IOError(filename, buf); 400 return Status::IOError(filename, buf);
187 } 401 }
188 402
189 Status MakeIOError(Slice filename, 403 Status MakeIOError(Slice filename,
190 const char* message, 404 const std::string& message,
191 MethodID method, 405 MethodID method) {
192 base::File::Error error) {
193 DCHECK_LT(error, 0);
194 char buf[512]; 406 char buf[512];
195 snprintf(buf, 407 snprintf(buf, sizeof(buf), "%s (ChromeMethodOnly: %d::%s)", message.c_str(),
196 sizeof(buf), 408 method, MethodIDToString(method));
197 "%s (ChromeMethodPFE: %d::%s::%d)",
198 message,
199 method,
200 MethodIDToString(method),
201 -error);
202 return Status::IOError(filename, buf); 409 return Status::IOError(filename, buf);
203 } 410 }
204 411
205 Status MakeIOError(Slice filename, const char* message, MethodID method) {
206 char buf[512];
207 snprintf(buf,
208 sizeof(buf),
209 "%s (ChromeMethodOnly: %d::%s)",
210 message,
211 method,
212 MethodIDToString(method));
213 return Status::IOError(filename, buf);
214 }
215
216 ErrorParsingResult ParseMethodAndError(const char* string, 412 ErrorParsingResult ParseMethodAndError(const char* string,
217 MethodID* method_param, 413 MethodID* method_param,
218 int* error) { 414 int* error) {
219 int method; 415 int method;
220 if (RE2::PartialMatch(string, "ChromeMethodOnly: (\\d+)", &method)) { 416 if (RE2::PartialMatch(string, "ChromeMethodOnly: (\\d+)", &method)) {
221 *method_param = static_cast<MethodID>(method); 417 *method_param = static_cast<MethodID>(method);
222 return METHOD_ONLY; 418 return METHOD_ONLY;
223 } 419 }
224 if (RE2::PartialMatch( 420 if (RE2::PartialMatch(
225 string, "ChromeMethodPFE: (\\d+)::.*::(\\d+)", &method, error)) { 421 string, "ChromeMethodPFE: (\\d+)::.*::(\\d+)", &method, error)) {
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 Status ChromiumEnv::GetChildren(const std::string& dir_string, 663 Status ChromiumEnv::GetChildren(const std::string& dir_string,
468 std::vector<std::string>* result) { 664 std::vector<std::string>* result) {
469 std::vector<base::FilePath> entries; 665 std::vector<base::FilePath> entries;
470 base::File::Error error = 666 base::File::Error error =
471 GetDirectoryEntries(CreateFilePath(dir_string), &entries); 667 GetDirectoryEntries(CreateFilePath(dir_string), &entries);
472 if (error != base::File::FILE_OK) { 668 if (error != base::File::FILE_OK) {
473 RecordOSError(kGetChildren, error); 669 RecordOSError(kGetChildren, error);
474 return MakeIOError( 670 return MakeIOError(
475 dir_string, "Could not open/read directory", kGetChildren, error); 671 dir_string, "Could not open/read directory", kGetChildren, error);
476 } 672 }
673
477 result->clear(); 674 result->clear();
478 for (std::vector<base::FilePath>::iterator it = entries.begin(); 675 for (const auto& entry : entries)
479 it != entries.end(); 676 result->push_back(FilePathToString(entry));
480 ++it) {
481 result->push_back(FilePathToString(*it));
482 }
483 677
484 if (make_backup_) 678 if (make_backup_)
485 RestoreIfNecessary(dir_string, result); 679 RestoreIfNecessary(dir_string, result);
680
486 return Status::OK(); 681 return Status::OK();
487 } 682 }
488 683
489 Status ChromiumEnv::DeleteFile(const std::string& fname) { 684 Status ChromiumEnv::DeleteFile(const std::string& fname) {
490 Status result; 685 Status result;
491 base::FilePath fname_filepath = CreateFilePath(fname); 686 base::FilePath fname_filepath = CreateFilePath(fname);
492 // TODO(jorlow): Should we assert this is a file? 687 // TODO(jorlow): Should we assert this is a file?
493 if (!::base::DeleteFile(fname_filepath, false)) { 688 if (!::base::DeleteFile(fname_filepath, false)) {
494 result = MakeIOError(fname, "Could not delete file.", kDeleteFile); 689 result = MakeIOError(fname, "Could not delete file.", kDeleteFile);
495 RecordErrorAt(kDeleteFile); 690 RecordErrorAt(kDeleteFile);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 RecordErrorAt(kGetTestDirectory); 843 RecordErrorAt(kGetTestDirectory);
649 return MakeIOError( 844 return MakeIOError(
650 "Could not create temp directory.", "", kGetTestDirectory); 845 "Could not create temp directory.", "", kGetTestDirectory);
651 } 846 }
652 } 847 }
653 *path = FilePathToString(test_directory_); 848 *path = FilePathToString(test_directory_);
654 mu_.Release(); 849 mu_.Release();
655 return Status::OK(); 850 return Status::OK();
656 } 851 }
657 852
853 Status ChromiumEnv::NewLogger(const std::string& fname,
854 leveldb::Logger** result) {
855 base::FilePath path = CreateFilePath(fname);
856 scoped_ptr<base::File> f(new base::File(
857 path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE));
858 if (!f->IsValid()) {
859 *result = NULL;
860 RecordOSError(kNewLogger, f->error_details());
861 return MakeIOError(fname, "Unable to create log file", kNewLogger,
862 f->error_details());
863 } else {
864 *result = new leveldb::ChromiumLogger(f.release());
865 return Status::OK();
866 }
867 }
868
869 Status ChromiumEnv::NewSequentialFile(const std::string& fname,
870 leveldb::SequentialFile** result) {
871 base::FilePath path = CreateFilePath(fname);
872 scoped_ptr<base::File> f(
873 new base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ));
874 if (!f->IsValid()) {
875 *result = NULL;
876 RecordOSError(kNewSequentialFile, f->error_details());
877 return MakeIOError(fname, "Unable to create sequential file",
878 kNewSequentialFile, f->error_details());
879 } else {
880 *result = new ChromiumSequentialFile(fname, f.release(), this);
881 return Status::OK();
882 }
883 }
884
885 void ChromiumEnv::RecordOpenFilesLimit(const std::string& type) {
886 #if defined(OS_POSIX)
887 GetMaxFDHistogram(type)->Add(base::GetMaxFds());
888 #elif defined(OS_WIN)
889 // Windows is only limited by available memory
890 #else
891 #error "Need to determine limit to open files for this OS"
892 #endif
893 }
894
895 Status ChromiumEnv::NewRandomAccessFile(const std::string& fname,
896 leveldb::RandomAccessFile** result) {
897 int flags = ::base::File::FLAG_READ | ::base::File::FLAG_OPEN;
898 ::base::File file(ChromiumEnv::CreateFilePath(fname), flags);
899 if (file.IsValid()) {
900 *result = new ChromiumRandomAccessFile(fname, file.Pass(), this);
901 RecordOpenFilesLimit("Success");
902 return Status::OK();
903 }
904 ::base::File::Error error_code = file.error_details();
905 if (error_code == ::base::File::FILE_ERROR_TOO_MANY_OPENED)
906 RecordOpenFilesLimit("TooManyOpened");
907 else
908 RecordOpenFilesLimit("OtherError");
909 *result = NULL;
910 RecordOSError(kNewRandomAccessFile, error_code);
911 return MakeIOError(fname, FileErrorString(error_code), kNewRandomAccessFile,
912 error_code);
913 }
914
915 Status ChromiumEnv::NewWritableFile(const std::string& fname,
916 leveldb::WritableFile** result) {
917 *result = NULL;
918 base::FilePath path = CreateFilePath(fname);
919 scoped_ptr<base::File> f(new base::File(
920 path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE));
921 if (!f->IsValid()) {
922 RecordErrorAt(kNewWritableFile);
923 return MakeIOError(fname, "Unable to create writable file",
924 kNewWritableFile, f->error_details());
925 } else {
926 *result =
927 new ChromiumWritableFile(fname, f.release(), this, this, make_backup_);
928 return Status::OK();
929 }
930 }
931
658 uint64_t ChromiumEnv::NowMicros() { 932 uint64_t ChromiumEnv::NowMicros() {
659 return ::base::TimeTicks::Now().ToInternalValue(); 933 return ::base::TimeTicks::Now().ToInternalValue();
660 } 934 }
661 935
662 void ChromiumEnv::SleepForMicroseconds(int micros) { 936 void ChromiumEnv::SleepForMicroseconds(int micros) {
663 // Round up to the next millisecond. 937 // Round up to the next millisecond.
664 ::base::PlatformThread::Sleep(::base::TimeDelta::FromMicroseconds(micros)); 938 ::base::PlatformThread::Sleep(::base::TimeDelta::FromMicroseconds(micros));
665 } 939 }
666 940
667 void ChromiumEnv::RecordErrorAt(MethodID method) const { 941 void ChromiumEnv::RecordErrorAt(MethodID method) const {
668 GetMethodIOErrorHistogram()->Add(method); 942 GetMethodIOErrorHistogram()->Add(method);
669 } 943 }
670 944
671 void ChromiumEnv::RecordLockFileAncestors(int num_missing_ancestors) const { 945 void ChromiumEnv::RecordLockFileAncestors(int num_missing_ancestors) const {
672 GetLockFileAncestorHistogram()->Add(num_missing_ancestors); 946 GetLockFileAncestorHistogram()->Add(num_missing_ancestors);
673 } 947 }
674 948
675 void ChromiumEnv::RecordOSError(MethodID method, 949 void ChromiumEnv::RecordOSError(MethodID method,
676 base::File::Error error) const { 950 base::File::Error error) const {
677 DCHECK_LT(error, 0); 951 DCHECK_LT(error, 0);
678 RecordErrorAt(method); 952 RecordErrorAt(method);
679 GetOSErrorHistogram(method, -base::File::FILE_ERROR_MAX)->Add(-error); 953 GetOSErrorHistogram(method, -base::File::FILE_ERROR_MAX)->Add(-error);
680 } 954 }
681 955
682 void ChromiumEnv::RecordOSError(MethodID method, int error) const {
683 DCHECK_GT(error, 0);
684 RecordErrorAt(method);
685 GetOSErrorHistogram(method, ERANGE + 1)->Add(error);
686 }
687
688 void ChromiumEnv::RecordBackupResult(bool result) const { 956 void ChromiumEnv::RecordBackupResult(bool result) const {
689 std::string uma_name(name_); 957 std::string uma_name(name_);
690 uma_name.append(".TableBackup"); 958 uma_name.append(".TableBackup");
691 base::BooleanHistogram::FactoryGet( 959 base::BooleanHistogram::FactoryGet(
692 uma_name, base::Histogram::kUmaTargetedHistogramFlag)->AddBoolean(result); 960 uma_name, base::Histogram::kUmaTargetedHistogramFlag)->AddBoolean(result);
693 } 961 }
694 962
695 base::HistogramBase* ChromiumEnv::GetOSErrorHistogram(MethodID method, 963 base::HistogramBase* ChromiumEnv::GetOSErrorHistogram(MethodID method,
696 int limit) const { 964 int limit) const {
697 std::string uma_name(name_); 965 std::string uma_name(name_);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 1026
759 class Thread : public ::base::PlatformThread::Delegate { 1027 class Thread : public ::base::PlatformThread::Delegate {
760 public: 1028 public:
761 Thread(void (*function)(void* arg), void* arg) 1029 Thread(void (*function)(void* arg), void* arg)
762 : function_(function), arg_(arg) { 1030 : function_(function), arg_(arg) {
763 ::base::PlatformThreadHandle handle; 1031 ::base::PlatformThreadHandle handle;
764 bool success = ::base::PlatformThread::Create(0, this, &handle); 1032 bool success = ::base::PlatformThread::Create(0, this, &handle);
765 DCHECK(success); 1033 DCHECK(success);
766 } 1034 }
767 virtual ~Thread() {} 1035 virtual ~Thread() {}
768 virtual void ThreadMain() { 1036 void ThreadMain() override {
769 (*function_)(arg_); 1037 (*function_)(arg_);
770 delete this; 1038 delete this;
771 } 1039 }
772 1040
773 private: 1041 private:
774 void (*function_)(void* arg); 1042 void (*function_)(void* arg);
775 void* arg_; 1043 void* arg_;
776 }; 1044 };
777 1045
778 void ChromiumEnv::Schedule(ScheduleFunc* function, void* arg) { 1046 void ChromiumEnv::Schedule(ScheduleFunc* function, void* arg) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 1116
849 Env* IDBEnv() { 1117 Env* IDBEnv() {
850 return leveldb_env::idb_env.Pointer(); 1118 return leveldb_env::idb_env.Pointer();
851 } 1119 }
852 1120
853 Env* Env::Default() { 1121 Env* Env::Default() {
854 return leveldb_env::default_env.Pointer(); 1122 return leveldb_env::default_env.Pointer();
855 } 1123 }
856 1124
857 } // namespace leveldb 1125 } // namespace leveldb
OLDNEW
« no previous file with comments | « third_party/leveldatabase/env_chromium.h ('k') | third_party/leveldatabase/env_chromium_stdio.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698