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

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

Issue 113373002: Unrevert r245135 "Created new Windows LevelDB environment." (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: IDB env always Win32, and other requested changes. Created 6 years, 11 months 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 <errno.h>
6 #include <stdio.h>
7 #include <string.h>
8
9 #include <deque>
10
11 #include "base/at_exit.h"
12 #include "base/debug/trace_event.h" 5 #include "base/debug/trace_event.h"
13 #include "base/file_util.h" 6 #include "base/file_util.h"
14 #include "base/files/file_enumerator.h"
15 #include "base/files/file_path.h"
16 #include "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
17 #include "base/memory/ref_counted.h"
18 #include "base/message_loop/message_loop.h"
19 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
20 #include "base/platform_file.h"
21 #include "base/posix/eintr_wrapper.h"
22 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
23 #include "base/synchronization/lock.h" 10 #include "env_chromium_stdio.h"
24 #include "base/sys_info.h"
25 #include "base/threading/platform_thread.h"
26 #include "base/threading/thread.h"
27 #include "chromium_logger.h"
28 #include "env_chromium.h"
29 #include "leveldb/env.h"
30 #include "leveldb/slice.h"
31 #include "port/port.h"
32 #include "third_party/re2/re2/re2.h" 11 #include "third_party/re2/re2/re2.h"
33 #include "util/logging.h"
34 12
35 #if defined(OS_WIN) 13 #if defined(OS_WIN)
36 #include <io.h> 14 #include <io.h>
15 #include "base/command_line.h"
37 #include "base/win/win_util.h" 16 #include "base/win/win_util.h"
38 #endif 17 #include "env_chromium_win.h"
39
40 #if defined(OS_POSIX)
41 #include <dirent.h>
42 #include <fcntl.h>
43 #include <sys/resource.h>
44 #include <sys/time.h>
45 #endif 18 #endif
46 19
47 using namespace leveldb; 20 using namespace leveldb;
48 21
49 namespace leveldb_env { 22 namespace leveldb_env {
50 23
51 namespace { 24 namespace {
52 25
53 const base::FilePath::CharType backup_table_extension[] = 26 const base::FilePath::CharType backup_table_extension[] =
54 FILE_PATH_LITERAL(".bak"); 27 FILE_PATH_LITERAL(".bak");
55 const base::FilePath::CharType table_extension[] = FILE_PATH_LITERAL(".ldb"); 28 const base::FilePath::CharType table_extension[] = FILE_PATH_LITERAL(".ldb");
56 29
57 #if (defined(OS_POSIX) && !defined(OS_LINUX)) || defined(OS_WIN)
58 // The following are glibc-specific
59
60 size_t fread_unlocked(void *ptr, size_t size, size_t n, FILE *file) {
61 return fread(ptr, size, n, file);
62 }
63
64 size_t fwrite_unlocked(const void *ptr, size_t size, size_t n, FILE *file) {
65 return fwrite(ptr, size, n, file);
66 }
67
68 int fflush_unlocked(FILE *file) {
69 return fflush(file);
70 }
71
72 #if !defined(OS_ANDROID)
73 int fdatasync(int fildes) {
74 #if defined(OS_WIN)
75 return _commit(fildes);
76 #else
77 return HANDLE_EINTR(fsync(fildes));
78 #endif
79 }
80 #endif
81
82 #endif
83
84 // Wide-char safe fopen wrapper.
85 FILE* fopen_internal(const char* fname, const char* mode) {
86 #if defined(OS_WIN)
87 return _wfopen(base::UTF8ToUTF16(fname).c_str(),
88 base::ASCIIToUTF16(mode).c_str());
89 #else
90 return fopen(fname, mode);
91 #endif
92 }
93
94 base::FilePath CreateFilePath(const std::string& file_path) {
95 #if defined(OS_WIN)
96 return base::FilePath(base::UTF8ToUTF16(file_path));
97 #else
98 return base::FilePath(file_path);
99 #endif
100 }
101
102 static const base::FilePath::CharType kLevelDBTestDirectoryPrefix[] 30 static const base::FilePath::CharType kLevelDBTestDirectoryPrefix[]
103 = FILE_PATH_LITERAL("leveldb-test-"); 31 = FILE_PATH_LITERAL("leveldb-test-");
104 32
105 const char* PlatformFileErrorString(const ::base::PlatformFileError& error) {
106 switch (error) {
107 case ::base::PLATFORM_FILE_ERROR_FAILED:
108 return "No further details.";
109 case ::base::PLATFORM_FILE_ERROR_IN_USE:
110 return "File currently in use.";
111 case ::base::PLATFORM_FILE_ERROR_EXISTS:
112 return "File already exists.";
113 case ::base::PLATFORM_FILE_ERROR_NOT_FOUND:
114 return "File not found.";
115 case ::base::PLATFORM_FILE_ERROR_ACCESS_DENIED:
116 return "Access denied.";
117 case ::base::PLATFORM_FILE_ERROR_TOO_MANY_OPENED:
118 return "Too many files open.";
119 case ::base::PLATFORM_FILE_ERROR_NO_MEMORY:
120 return "Out of memory.";
121 case ::base::PLATFORM_FILE_ERROR_NO_SPACE:
122 return "No space left on drive.";
123 case ::base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY:
124 return "Not a directory.";
125 case ::base::PLATFORM_FILE_ERROR_INVALID_OPERATION:
126 return "Invalid operation.";
127 case ::base::PLATFORM_FILE_ERROR_SECURITY:
128 return "Security error.";
129 case ::base::PLATFORM_FILE_ERROR_ABORT:
130 return "File operation aborted.";
131 case ::base::PLATFORM_FILE_ERROR_NOT_A_FILE:
132 return "The supplied path was not a file.";
133 case ::base::PLATFORM_FILE_ERROR_NOT_EMPTY:
134 return "The file was not empty.";
135 case ::base::PLATFORM_FILE_ERROR_INVALID_URL:
136 return "Invalid URL.";
137 case ::base::PLATFORM_FILE_ERROR_IO:
138 return "OS or hardware error.";
139 case ::base::PLATFORM_FILE_OK:
140 return "OK.";
141 case ::base::PLATFORM_FILE_ERROR_MAX:
142 NOTREACHED();
143 }
144 NOTIMPLEMENTED();
145 return "Unknown error.";
146 }
147
148 class ChromiumSequentialFile: public SequentialFile {
149 private:
150 std::string filename_;
151 FILE* file_;
152 const UMALogger* uma_logger_;
153
154 public:
155 ChromiumSequentialFile(const std::string& fname, FILE* f,
156 const UMALogger* uma_logger)
157 : filename_(fname), file_(f), uma_logger_(uma_logger) { }
158 virtual ~ChromiumSequentialFile() { fclose(file_); }
159
160 virtual Status Read(size_t n, Slice* result, char* scratch) {
161 Status s;
162 size_t r = fread_unlocked(scratch, 1, n, file_);
163 *result = Slice(scratch, r);
164 if (r < n) {
165 if (feof(file_)) {
166 // We leave status as ok if we hit the end of the file
167 } else {
168 // A partial read with an error: return a non-ok status
169 s = MakeIOError(filename_, strerror(errno), kSequentialFileRead, errno);
170 uma_logger_->RecordErrorAt(kSequentialFileRead);
171 }
172 }
173 return s;
174 }
175
176 virtual Status Skip(uint64_t n) {
177 if (fseek(file_, n, SEEK_CUR)) {
178 int saved_errno = errno;
179 uma_logger_->RecordErrorAt(kSequentialFileSkip);
180 return MakeIOError(
181 filename_, strerror(saved_errno), kSequentialFileSkip, saved_errno);
182 }
183 return Status::OK();
184 }
185 };
186
187 class ChromiumRandomAccessFile: public RandomAccessFile {
188 private:
189 std::string filename_;
190 ::base::PlatformFile file_;
191 const UMALogger* uma_logger_;
192
193 public:
194 ChromiumRandomAccessFile(const std::string& fname, ::base::PlatformFile file,
195 const UMALogger* uma_logger)
196 : filename_(fname), file_(file), uma_logger_(uma_logger) { }
197 virtual ~ChromiumRandomAccessFile() { ::base::ClosePlatformFile(file_); }
198
199 virtual Status Read(uint64_t offset, size_t n, Slice* result,
200 char* scratch) const {
201 Status s;
202 int r = ::base::ReadPlatformFile(file_, offset, scratch, n);
203 *result = Slice(scratch, (r < 0) ? 0 : r);
204 if (r < 0) {
205 // An error: return a non-ok status
206 s = MakeIOError(
207 filename_, "Could not perform read", kRandomAccessFileRead);
208 uma_logger_->RecordErrorAt(kRandomAccessFileRead);
209 }
210 return s;
211 }
212 };
213
214 class ChromiumFileLock : public FileLock { 33 class ChromiumFileLock : public FileLock {
215 public: 34 public:
216 ::base::PlatformFile file_; 35 ::base::PlatformFile file_;
217 std::string name_; 36 std::string name_;
218 }; 37 };
219 38
220 class Retrier { 39 class Retrier {
221 public: 40 public:
222 Retrier(MethodID method, RetrierProvider* provider) 41 Retrier(MethodID method, RetrierProvider* provider)
223 : start_(base::TimeTicks::Now()), 42 : start_(base::TimeTicks::Now()),
(...skipping 30 matching lines...) Expand all
254 base::TimeTicks start_; 73 base::TimeTicks start_;
255 base::TimeTicks limit_; 74 base::TimeTicks limit_;
256 base::TimeTicks last_; 75 base::TimeTicks last_;
257 base::TimeDelta time_to_sleep_; 76 base::TimeDelta time_to_sleep_;
258 bool success_; 77 bool success_;
259 MethodID method_; 78 MethodID method_;
260 base::PlatformFileError last_error_; 79 base::PlatformFileError last_error_;
261 RetrierProvider* provider_; 80 RetrierProvider* provider_;
262 }; 81 };
263 82
264 class IDBEnv : public ChromiumEnv { 83 class IDBEnvStdio : public ChromiumEnvStdio {
265 public: 84 public:
266 IDBEnv() : ChromiumEnv() { 85 IDBEnvStdio() : ChromiumEnvStdio() {
267 name_ = "LevelDBEnv.IDB"; 86 name_ = "LevelDBEnv.IDB";
268 make_backup_ = true; 87 make_backup_ = true;
269 } 88 }
270 }; 89 };
271 90
272 ::base::LazyInstance<IDBEnv>::Leaky idb_env = LAZY_INSTANCE_INITIALIZER; 91 #if defined(OS_WIN)
92 class IDBEnvWin : public ChromiumEnvWin {
93 public:
94 IDBEnvWin() : ChromiumEnvWin() {
95 name_ = "LevelDBEnv.IDB";
96 make_backup_ = true;
97 }
98 };
99 #endif
273 100
274 ::base::LazyInstance<ChromiumEnv>::Leaky default_env = 101 #if defined(OS_WIN)
102 ::base::LazyInstance<IDBEnvWin>::Leaky idb_env =
103 LAZY_INSTANCE_INITIALIZER;
104 #else
105 ::base::LazyInstance<IDBEnvStdio>::Leaky idb_env =
106 LAZY_INSTANCE_INITIALIZER;
107 #endif
108
109 ::base::LazyInstance<ChromiumEnvStdio>::Leaky default_env =
275 LAZY_INSTANCE_INITIALIZER; 110 LAZY_INSTANCE_INITIALIZER;
276 111
277 } // unnamed namespace 112 } // unnamed namespace
278 113
279 const char* MethodIDToString(MethodID method) { 114 const char* MethodIDToString(MethodID method) {
280 switch (method) { 115 switch (method) {
281 case kSequentialFileRead: 116 case kSequentialFileRead:
282 return "SequentialFileRead"; 117 return "SequentialFileRead";
283 case kSequentialFileSkip: 118 case kSequentialFileSkip:
284 return "SequentialFileSkip"; 119 return "SequentialFileSkip";
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 } 322 }
488 323
489 std::string FilePathToString(const base::FilePath& file_path) { 324 std::string FilePathToString(const base::FilePath& file_path) {
490 #if defined(OS_WIN) 325 #if defined(OS_WIN)
491 return base::UTF16ToUTF8(file_path.value()); 326 return base::UTF16ToUTF8(file_path.value());
492 #else 327 #else
493 return file_path.value(); 328 return file_path.value();
494 #endif 329 #endif
495 } 330 }
496 331
497 ChromiumWritableFile::ChromiumWritableFile(const std::string& fname, 332 base::FilePath ChromiumEnv::CreateFilePath(const std::string& file_path) {
498 FILE* f, 333 #if defined(OS_WIN)
499 const UMALogger* uma_logger, 334 return base::FilePath(base::UTF8ToUTF16(file_path));
500 WriteTracker* tracker, 335 #else
501 bool make_backup) 336 return base::FilePath(file_path);
502 : filename_(fname), 337 #endif
503 file_(f),
504 uma_logger_(uma_logger),
505 tracker_(tracker),
506 file_type_(kOther),
507 make_backup_(make_backup) {
508 base::FilePath path = base::FilePath::FromUTF8Unsafe(fname);
509 if (FilePathToString(path.BaseName()).find("MANIFEST") == 0)
510 file_type_ = kManifest;
511 else if (path.MatchesExtension(table_extension))
512 file_type_ = kTable;
513 if (file_type_ != kManifest)
514 tracker_->DidCreateNewFile(filename_);
515 parent_dir_ = FilePathToString(CreateFilePath(fname).DirName());
516 } 338 }
517 339
518 ChromiumWritableFile::~ChromiumWritableFile() { 340 bool ChromiumEnv::MakeBackup(const std::string& fname) {
519 if (file_ != NULL) {
520 // Ignoring any potential errors
521 fclose(file_);
522 }
523 }
524
525 Status ChromiumWritableFile::SyncParent() {
526 Status s;
527 #if !defined(OS_WIN)
528 TRACE_EVENT0("leveldb", "SyncParent");
529
530 int parent_fd =
531 HANDLE_EINTR(open(parent_dir_.c_str(), O_RDONLY));
532 if (parent_fd < 0) {
533 int saved_errno = errno;
534 return MakeIOError(
535 parent_dir_, strerror(saved_errno), kSyncParent, saved_errno);
536 }
537 if (HANDLE_EINTR(fsync(parent_fd)) != 0) {
538 int saved_errno = errno;
539 s = MakeIOError(
540 parent_dir_, strerror(saved_errno), kSyncParent, saved_errno);
541 };
542 close(parent_fd);
543 #endif
544 return s;
545 }
546
547 Status ChromiumWritableFile::Append(const Slice& data) {
548 if (file_type_ == kManifest && tracker_->DoesDirNeedSync(filename_)) {
549 Status s = SyncParent();
550 if (!s.ok())
551 return s;
552 tracker_->DidSyncDir(filename_);
553 }
554
555 size_t r = fwrite_unlocked(data.data(), 1, data.size(), file_);
556 if (r != data.size()) {
557 int saved_errno = errno;
558 uma_logger_->RecordOSError(kWritableFileAppend, saved_errno);
559 return MakeIOError(
560 filename_, strerror(saved_errno), kWritableFileAppend, saved_errno);
561 }
562 return Status::OK();
563 }
564
565 Status ChromiumWritableFile::Close() {
566 Status result;
567 if (fclose(file_) != 0) {
568 result = MakeIOError(filename_, strerror(errno), kWritableFileClose, errno);
569 uma_logger_->RecordErrorAt(kWritableFileClose);
570 }
571 file_ = NULL;
572 return result;
573 }
574
575 Status ChromiumWritableFile::Flush() {
576 Status result;
577 if (HANDLE_EINTR(fflush_unlocked(file_))) {
578 int saved_errno = errno;
579 result = MakeIOError(
580 filename_, strerror(saved_errno), kWritableFileFlush, saved_errno);
581 uma_logger_->RecordOSError(kWritableFileFlush, saved_errno);
582 }
583 return result;
584 }
585
586 static bool MakeBackup(const std::string& fname) {
587 base::FilePath original_table_name = CreateFilePath(fname); 341 base::FilePath original_table_name = CreateFilePath(fname);
588 base::FilePath backup_table_name = 342 base::FilePath backup_table_name =
589 original_table_name.ReplaceExtension(backup_table_extension); 343 original_table_name.ReplaceExtension(backup_table_extension);
590 return base::CopyFile(original_table_name, backup_table_name); 344 return base::CopyFile(original_table_name, backup_table_name);
591 } 345 }
592 346
593 Status ChromiumWritableFile::Sync() { 347 bool ChromiumEnv::HasTableExtension(const base::FilePath& path)
594 TRACE_EVENT0("leveldb", "ChromiumEnv::Sync"); 348 {
595 Status result; 349 return path.MatchesExtension(table_extension);
596 int error = 0;
597
598 if (HANDLE_EINTR(fflush_unlocked(file_)))
599 error = errno;
600 // Sync even if fflush gave an error; perhaps the data actually got out,
601 // even though something went wrong.
602 if (fdatasync(fileno(file_)) && !error)
603 error = errno;
604 // Report the first error we found.
605 if (error) {
606 result = MakeIOError(filename_, strerror(error), kWritableFileSync, error);
607 uma_logger_->RecordErrorAt(kWritableFileSync);
608 } else if (make_backup_ && file_type_ == kTable) {
609 bool success = MakeBackup(filename_);
610 uma_logger_->RecordBackupResult(success);
611 }
612 return result;
613 } 350 }
614 351
615 ChromiumEnv::ChromiumEnv() 352 ChromiumEnv::ChromiumEnv()
616 : name_("LevelDBEnv"), 353 : name_("LevelDBEnv"),
617 make_backup_(false), 354 make_backup_(false),
618 bgsignal_(&mu_), 355 bgsignal_(&mu_),
619 started_bgthread_(false), 356 started_bgthread_(false),
620 kMaxRetryTimeMillis(1000) { 357 kMaxRetryTimeMillis(1000) {
621 } 358 }
622 359
623 ChromiumEnv::~ChromiumEnv() { 360 ChromiumEnv::~ChromiumEnv() {
624 // In chromium, ChromiumEnv is leaked. It'd be nice to add NOTREACHED here to 361 // In chromium, ChromiumEnv is leaked. It'd be nice to add NOTREACHED here to
625 // ensure that behavior isn't accidentally changed, but there's an instance in 362 // ensure that behavior isn't accidentally changed, but there's an instance in
626 // a unit test that is deleted. 363 // a unit test that is deleted.
627 } 364 }
628 365
629 Status ChromiumEnv::NewSequentialFile(const std::string& fname,
630 SequentialFile** result) {
631 FILE* f = fopen_internal(fname.c_str(), "rb");
632 if (f == NULL) {
633 *result = NULL;
634 int saved_errno = errno;
635 RecordOSError(kNewSequentialFile, saved_errno);
636 return MakeIOError(
637 fname, strerror(saved_errno), kNewSequentialFile, saved_errno);
638 } else {
639 *result = new ChromiumSequentialFile(fname, f, this);
640 return Status::OK();
641 }
642 }
643
644 void ChromiumEnv::RecordOpenFilesLimit(const std::string& type) {
645 #if defined(OS_POSIX)
646 struct rlimit nofile;
647 if (getrlimit(RLIMIT_NOFILE, &nofile))
648 return;
649 GetMaxFDHistogram(type)->Add(nofile.rlim_cur);
650 #endif
651 }
652
653 Status ChromiumEnv::NewRandomAccessFile(const std::string& fname,
654 RandomAccessFile** result) {
655 int flags = ::base::PLATFORM_FILE_READ | ::base::PLATFORM_FILE_OPEN;
656 bool created;
657 ::base::PlatformFileError error_code;
658 ::base::PlatformFile file = ::base::CreatePlatformFile(
659 CreateFilePath(fname), flags, &created, &error_code);
660 if (error_code == ::base::PLATFORM_FILE_OK) {
661 *result = new ChromiumRandomAccessFile(fname, file, this);
662 RecordOpenFilesLimit("Success");
663 return Status::OK();
664 }
665 if (error_code == ::base::PLATFORM_FILE_ERROR_TOO_MANY_OPENED)
666 RecordOpenFilesLimit("TooManyOpened");
667 else
668 RecordOpenFilesLimit("OtherError");
669 *result = NULL;
670 RecordOSError(kNewRandomAccessFile, error_code);
671 return MakeIOError(fname,
672 PlatformFileErrorString(error_code),
673 kNewRandomAccessFile,
674 error_code);
675 }
676
677 Status ChromiumEnv::NewWritableFile(const std::string& fname,
678 WritableFile** result) {
679 *result = NULL;
680 FILE* f = fopen_internal(fname.c_str(), "wb");
681 if (f == NULL) {
682 int saved_errno = errno;
683 RecordErrorAt(kNewWritableFile);
684 return MakeIOError(
685 fname, strerror(saved_errno), kNewWritableFile, saved_errno);
686 } else {
687 *result = new ChromiumWritableFile(fname, f, this, this, make_backup_);
688 return Status::OK();
689 }
690 }
691
692 bool ChromiumEnv::FileExists(const std::string& fname) { 366 bool ChromiumEnv::FileExists(const std::string& fname) {
693 return ::base::PathExists(CreateFilePath(fname)); 367 return ::base::PathExists(CreateFilePath(fname));
694 } 368 }
695 369
370 const char* ChromiumEnv::PlatformFileErrorString(const ::base::PlatformFileError & error) {
371 switch (error) {
372 case ::base::PLATFORM_FILE_ERROR_FAILED:
373 return "No further details.";
374 case ::base::PLATFORM_FILE_ERROR_IN_USE:
375 return "File currently in use.";
376 case ::base::PLATFORM_FILE_ERROR_EXISTS:
377 return "File already exists.";
378 case ::base::PLATFORM_FILE_ERROR_NOT_FOUND:
379 return "File not found.";
380 case ::base::PLATFORM_FILE_ERROR_ACCESS_DENIED:
381 return "Access denied.";
382 case ::base::PLATFORM_FILE_ERROR_TOO_MANY_OPENED:
383 return "Too many files open.";
384 case ::base::PLATFORM_FILE_ERROR_NO_MEMORY:
385 return "Out of memory.";
386 case ::base::PLATFORM_FILE_ERROR_NO_SPACE:
387 return "No space left on drive.";
388 case ::base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY:
389 return "Not a directory.";
390 case ::base::PLATFORM_FILE_ERROR_INVALID_OPERATION:
391 return "Invalid operation.";
392 case ::base::PLATFORM_FILE_ERROR_SECURITY:
393 return "Security error.";
394 case ::base::PLATFORM_FILE_ERROR_ABORT:
395 return "File operation aborted.";
396 case ::base::PLATFORM_FILE_ERROR_NOT_A_FILE:
397 return "The supplied path was not a file.";
398 case ::base::PLATFORM_FILE_ERROR_NOT_EMPTY:
399 return "The file was not empty.";
400 case ::base::PLATFORM_FILE_ERROR_INVALID_URL:
401 return "Invalid URL.";
402 case ::base::PLATFORM_FILE_ERROR_IO:
403 return "OS or hardware error.";
404 case ::base::PLATFORM_FILE_OK:
405 return "OK.";
406 case ::base::PLATFORM_FILE_ERROR_MAX:
407 NOTREACHED();
408 }
409 NOTIMPLEMENTED();
410 return "Unknown error.";
411 }
412
696 base::FilePath ChromiumEnv::RestoreFromBackup(const base::FilePath& base_name) { 413 base::FilePath ChromiumEnv::RestoreFromBackup(const base::FilePath& base_name) {
697 base::FilePath table_name = 414 base::FilePath table_name =
698 base_name.AddExtension(table_extension); 415 base_name.AddExtension(table_extension);
699 bool result = base::CopyFile(base_name.AddExtension(backup_table_extension), 416 bool result = base::CopyFile(base_name.AddExtension(backup_table_extension),
700 table_name); 417 table_name);
701 std::string uma_name(name_); 418 std::string uma_name(name_);
702 uma_name.append(".TableRestore"); 419 uma_name.append(".TableRestore");
703 base::BooleanHistogram::FactoryGet( 420 base::BooleanHistogram::FactoryGet(
704 uma_name, base::Histogram::kUmaTargetedHistogramFlag)->AddBoolean(result); 421 uma_name, base::Histogram::kUmaTargetedHistogramFlag)->AddBoolean(result);
705 return table_name; 422 return table_name;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 base::FilePath dir_filepath = base::FilePath::FromUTF8Unsafe(dir); 456 base::FilePath dir_filepath = base::FilePath::FromUTF8Unsafe(dir);
740 for (std::set<base::FilePath>::iterator it = backups_only.begin(); 457 for (std::set<base::FilePath>::iterator it = backups_only.begin();
741 it != backups_only.end(); 458 it != backups_only.end();
742 ++it) { 459 ++it) {
743 base::FilePath restored_table_name = 460 base::FilePath restored_table_name =
744 RestoreFromBackup(dir_filepath.Append(*it)); 461 RestoreFromBackup(dir_filepath.Append(*it));
745 result->push_back(FilePathToString(restored_table_name.BaseName())); 462 result->push_back(FilePathToString(restored_table_name.BaseName()));
746 } 463 }
747 } 464 }
748 465
749 namespace {
750 #if defined(OS_WIN)
751 static base::PlatformFileError GetDirectoryEntries(
752 const base::FilePath& dir_param,
753 std::vector<base::FilePath>* result) {
754 result->clear();
755 base::FilePath dir_filepath = dir_param.Append(FILE_PATH_LITERAL("*"));
756 WIN32_FIND_DATA find_data;
757 HANDLE find_handle = FindFirstFile(dir_filepath.value().c_str(), &find_data);
758 if (find_handle == INVALID_HANDLE_VALUE) {
759 DWORD last_error = GetLastError();
760 if (last_error == ERROR_FILE_NOT_FOUND)
761 return base::PLATFORM_FILE_OK;
762 return base::LastErrorToPlatformFileError(last_error);
763 }
764 do {
765 base::FilePath filepath(find_data.cFileName);
766 base::FilePath::StringType basename = filepath.BaseName().value();
767 if (basename == FILE_PATH_LITERAL(".") ||
768 basename == FILE_PATH_LITERAL(".."))
769 continue;
770 result->push_back(filepath.BaseName());
771 } while (FindNextFile(find_handle, &find_data));
772 DWORD last_error = GetLastError();
773 base::PlatformFileError return_value = base::PLATFORM_FILE_OK;
774 if (last_error != ERROR_NO_MORE_FILES)
775 return_value = base::LastErrorToPlatformFileError(last_error);
776 FindClose(find_handle);
777 return return_value;
778 }
779 #else
780 static base::PlatformFileError GetDirectoryEntries(
781 const base::FilePath& dir_filepath,
782 std::vector<base::FilePath>* result) {
783 const std::string dir_string = FilePathToString(dir_filepath);
784 result->clear();
785 DIR* dir = opendir(dir_string.c_str());
786 if (!dir)
787 return base::ErrnoToPlatformFileError(errno);
788 struct dirent dent_buf;
789 struct dirent* dent;
790 int readdir_result;
791 while ((readdir_result = readdir_r(dir, &dent_buf, &dent)) == 0 && dent) {
792 if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0)
793 continue;
794 result->push_back(CreateFilePath(dent->d_name));
795 }
796 int saved_errno = errno;
797 closedir(dir);
798 if (readdir_result != 0)
799 return base::ErrnoToPlatformFileError(saved_errno);
800 return base::PLATFORM_FILE_OK;
801 }
802 #endif
803 }
804
805 Status ChromiumEnv::GetChildren(const std::string& dir_string, 466 Status ChromiumEnv::GetChildren(const std::string& dir_string,
806 std::vector<std::string>* result) { 467 std::vector<std::string>* result) {
807 std::vector<base::FilePath> entries; 468 std::vector<base::FilePath> entries;
808 base::PlatformFileError error = 469 base::PlatformFileError error =
809 GetDirectoryEntries(CreateFilePath(dir_string), &entries); 470 GetDirectoryEntries(CreateFilePath(dir_string), &entries);
810 if (error != base::PLATFORM_FILE_OK) { 471 if (error != base::PLATFORM_FILE_OK) {
811 RecordOSError(kGetChildren, error); 472 RecordOSError(kGetChildren, error);
812 return MakeIOError( 473 return MakeIOError(
813 dir_string, "Could not open/read directory", kGetChildren, error); 474 dir_string, "Could not open/read directory", kGetChildren, error);
814 } 475 }
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 RecordErrorAt(kGetTestDirectory); 656 RecordErrorAt(kGetTestDirectory);
996 return MakeIOError( 657 return MakeIOError(
997 "Could not create temp directory.", "", kGetTestDirectory); 658 "Could not create temp directory.", "", kGetTestDirectory);
998 } 659 }
999 } 660 }
1000 *path = FilePathToString(test_directory_); 661 *path = FilePathToString(test_directory_);
1001 mu_.Release(); 662 mu_.Release();
1002 return Status::OK(); 663 return Status::OK();
1003 } 664 }
1004 665
1005 Status ChromiumEnv::NewLogger(const std::string& fname, Logger** result) {
1006 FILE* f = fopen_internal(fname.c_str(), "w");
1007 if (f == NULL) {
1008 *result = NULL;
1009 int saved_errno = errno;
1010 RecordOSError(kNewLogger, saved_errno);
1011 return MakeIOError(fname, strerror(saved_errno), kNewLogger, saved_errno);
1012 } else {
1013 *result = new ChromiumLogger(f);
1014 return Status::OK();
1015 }
1016 }
1017
1018 uint64_t ChromiumEnv::NowMicros() { 666 uint64_t ChromiumEnv::NowMicros() {
1019 return ::base::TimeTicks::Now().ToInternalValue(); 667 return ::base::TimeTicks::Now().ToInternalValue();
1020 } 668 }
1021 669
1022 void ChromiumEnv::SleepForMicroseconds(int micros) { 670 void ChromiumEnv::SleepForMicroseconds(int micros) {
1023 // Round up to the next millisecond. 671 // Round up to the next millisecond.
1024 ::base::PlatformThread::Sleep(::base::TimeDelta::FromMicroseconds(micros)); 672 ::base::PlatformThread::Sleep(::base::TimeDelta::FromMicroseconds(micros));
1025 } 673 }
1026 674
1027 void ChromiumEnv::RecordErrorAt(MethodID method) const { 675 void ChromiumEnv::RecordErrorAt(MethodID method) const {
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 Env* IDBEnv() { 857 Env* IDBEnv() {
1210 return leveldb_env::idb_env.Pointer(); 858 return leveldb_env::idb_env.Pointer();
1211 } 859 }
1212 860
1213 Env* Env::Default() { 861 Env* Env::Default() {
1214 return leveldb_env::default_env.Pointer(); 862 return leveldb_env::default_env.Pointer();
1215 } 863 }
1216 864
1217 } // namespace leveldb 865 } // namespace leveldb
1218 866
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698