Chromium Code Reviews| 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 <deque> | 5 #include <deque> |
| 6 #include <errno.h> | 6 #include <errno.h> |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 #include "base/at_exit.h" | 8 #include "base/at_exit.h" |
| 9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 #include "leveldb/env.h" | 24 #include "leveldb/env.h" |
| 25 #include "leveldb/slice.h" | 25 #include "leveldb/slice.h" |
| 26 #include "port/port.h" | 26 #include "port/port.h" |
| 27 #include "util/logging.h" | 27 #include "util/logging.h" |
| 28 | 28 |
| 29 #if defined(OS_WIN) | 29 #if defined(OS_WIN) |
| 30 #include <io.h> | 30 #include <io.h> |
| 31 #include "base/win/win_util.h" | 31 #include "base/win/win_util.h" |
| 32 #endif | 32 #endif |
| 33 | 33 |
| 34 #if !defined(OS_WIN) | |
| 35 #include <fcntl.h> | |
| 36 #endif | |
| 37 | |
| 34 namespace { | 38 namespace { |
| 35 | 39 |
| 36 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID) || \ | 40 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID) || \ |
| 37 defined(OS_OPENBSD) | 41 defined(OS_OPENBSD) |
| 38 // The following are glibc-specific | 42 // The following are glibc-specific |
| 39 | 43 |
| 40 size_t fread_unlocked(void *ptr, size_t size, size_t n, FILE *file) { | 44 size_t fread_unlocked(void *ptr, size_t size, size_t n, FILE *file) { |
| 41 return fread(ptr, size, n, file); | 45 return fread(ptr, size, n, file); |
| 42 } | 46 } |
| 43 | 47 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 63 | 67 |
| 64 // Wide-char safe fopen wrapper. | 68 // Wide-char safe fopen wrapper. |
| 65 FILE* fopen_internal(const char* fname, const char* mode) { | 69 FILE* fopen_internal(const char* fname, const char* mode) { |
| 66 #if defined(OS_WIN) | 70 #if defined(OS_WIN) |
| 67 return _wfopen(UTF8ToUTF16(fname).c_str(), ASCIIToUTF16(mode).c_str()); | 71 return _wfopen(UTF8ToUTF16(fname).c_str(), ASCIIToUTF16(mode).c_str()); |
| 68 #else | 72 #else |
| 69 return fopen(fname, mode); | 73 return fopen(fname, mode); |
| 70 #endif | 74 #endif |
| 71 } | 75 } |
| 72 | 76 |
| 77 ::FilePath CreateFilePath(const std::string& file_path) { | |
| 78 #if defined(OS_WIN) | |
| 79 return FilePath(UTF8ToUTF16(file_path)); | |
| 80 #else | |
| 81 return FilePath(file_path); | |
| 82 #endif | |
| 83 } | |
| 84 | |
| 85 std::string FilePathToString(const ::FilePath& file_path) { | |
| 86 #if defined(OS_WIN) | |
| 87 return UTF16ToUTF8(file_path.value()); | |
| 88 #else | |
| 89 return file_path.value(); | |
| 90 #endif | |
| 91 } | |
| 92 | |
| 93 bool sync_parent(const std::string& fname) { | |
| 94 #if !defined(OS_WIN) | |
|
dgrogan
2013/05/28 22:02:19
What was the impetus for skipping this on windows?
ericu
2013/05/28 22:05:25
I asked Siggi, and he said that on Windows there w
| |
| 95 FilePath parent_dir = CreateFilePath(fname).DirName(); | |
| 96 int parent_fd = open(FilePathToString(parent_dir).c_str(), O_RDONLY); | |
| 97 if (parent_fd < 0) | |
| 98 return false; | |
| 99 fsync(parent_fd); | |
| 100 close(parent_fd); | |
| 101 #endif | |
| 102 return true; | |
| 103 } | |
| 104 | |
| 73 enum UmaEntry { | 105 enum UmaEntry { |
| 74 kSequentialFileRead, | 106 kSequentialFileRead, |
| 75 kSequentialFileSkip, | 107 kSequentialFileSkip, |
| 76 kRandomAccessFileRead, | 108 kRandomAccessFileRead, |
| 77 kWritableFileAppend, | 109 kWritableFileAppend, |
| 78 kWritableFileClose, | 110 kWritableFileClose, |
| 79 kWritableFileFlush, | 111 kWritableFileFlush, |
| 80 kWritableFileSync, | 112 kWritableFileSync, |
| 81 kNewSequentialFile, | 113 kNewSequentialFile, |
| 82 kNewRandomAccessFile, | 114 kNewRandomAccessFile, |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 101 | 133 |
| 102 namespace leveldb { | 134 namespace leveldb { |
| 103 | 135 |
| 104 namespace { | 136 namespace { |
| 105 | 137 |
| 106 class Thread; | 138 class Thread; |
| 107 | 139 |
| 108 static const ::FilePath::CharType kLevelDBTestDirectoryPrefix[] | 140 static const ::FilePath::CharType kLevelDBTestDirectoryPrefix[] |
| 109 = FILE_PATH_LITERAL("leveldb-test-"); | 141 = FILE_PATH_LITERAL("leveldb-test-"); |
| 110 | 142 |
| 111 ::FilePath CreateFilePath(const std::string& file_path) { | |
| 112 #if defined(OS_WIN) | |
| 113 return FilePath(UTF8ToUTF16(file_path)); | |
| 114 #else | |
| 115 return FilePath(file_path); | |
| 116 #endif | |
| 117 } | |
| 118 | |
| 119 std::string FilePathToString(const ::FilePath& file_path) { | |
| 120 #if defined(OS_WIN) | |
| 121 return UTF16ToUTF8(file_path.value()); | |
| 122 #else | |
| 123 return file_path.value(); | |
| 124 #endif | |
| 125 } | |
| 126 | |
| 127 // TODO(jorlow): This should be moved into Chromium's base. | 143 // TODO(jorlow): This should be moved into Chromium's base. |
| 128 const char* PlatformFileErrorString(const ::base::PlatformFileError& error) { | 144 const char* PlatformFileErrorString(const ::base::PlatformFileError& error) { |
| 129 switch (error) { | 145 switch (error) { |
| 130 case ::base::PLATFORM_FILE_ERROR_FAILED: | 146 case ::base::PLATFORM_FILE_ERROR_FAILED: |
| 131 return "Opening file failed."; | 147 return "Opening file failed."; |
| 132 case ::base::PLATFORM_FILE_ERROR_IN_USE: | 148 case ::base::PLATFORM_FILE_ERROR_IN_USE: |
| 133 return "File currently in use."; | 149 return "File currently in use."; |
| 134 case ::base::PLATFORM_FILE_ERROR_EXISTS: | 150 case ::base::PLATFORM_FILE_ERROR_EXISTS: |
| 135 return "File already exists."; | 151 return "File already exists."; |
| 136 case ::base::PLATFORM_FILE_ERROR_NOT_FOUND: | 152 case ::base::PLATFORM_FILE_ERROR_NOT_FOUND: |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 321 } | 337 } |
| 322 | 338 |
| 323 virtual Status NewWritableFile(const std::string& fname, | 339 virtual Status NewWritableFile(const std::string& fname, |
| 324 WritableFile** result) { | 340 WritableFile** result) { |
| 325 *result = NULL; | 341 *result = NULL; |
| 326 FILE* f = fopen_internal(fname.c_str(), "wb"); | 342 FILE* f = fopen_internal(fname.c_str(), "wb"); |
| 327 if (f == NULL) { | 343 if (f == NULL) { |
| 328 LogToUMA(kNewWritableFile); | 344 LogToUMA(kNewWritableFile); |
| 329 return Status::IOError(fname, strerror(errno)); | 345 return Status::IOError(fname, strerror(errno)); |
| 330 } else { | 346 } else { |
| 347 if (!sync_parent(fname)) { | |
| 348 fclose(f); | |
| 349 return Status::IOError(fname, strerror(errno)); | |
| 350 } | |
| 331 *result = new ChromiumWritableFile(fname, f); | 351 *result = new ChromiumWritableFile(fname, f); |
| 332 return Status::OK(); | 352 return Status::OK(); |
| 333 } | 353 } |
| 334 } | 354 } |
| 335 | 355 |
| 336 virtual bool FileExists(const std::string& fname) { | 356 virtual bool FileExists(const std::string& fname) { |
| 337 return ::file_util::PathExists(CreateFilePath(fname)); | 357 return ::file_util::PathExists(CreateFilePath(fname)); |
| 338 } | 358 } |
| 339 | 359 |
| 340 virtual Status GetChildren(const std::string& dir, | 360 virtual Status GetChildren(const std::string& dir, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 393 *size = static_cast<uint64_t>(signed_size); | 413 *size = static_cast<uint64_t>(signed_size); |
| 394 } | 414 } |
| 395 return s; | 415 return s; |
| 396 } | 416 } |
| 397 | 417 |
| 398 virtual Status RenameFile(const std::string& src, const std::string& dst) { | 418 virtual Status RenameFile(const std::string& src, const std::string& dst) { |
| 399 Status result; | 419 Status result; |
| 400 if (!::file_util::ReplaceFile(CreateFilePath(src), CreateFilePath(dst))) { | 420 if (!::file_util::ReplaceFile(CreateFilePath(src), CreateFilePath(dst))) { |
| 401 result = Status::IOError(src, "Could not rename file."); | 421 result = Status::IOError(src, "Could not rename file."); |
| 402 LogToUMA(kRenamefile); | 422 LogToUMA(kRenamefile); |
| 423 } else { | |
| 424 sync_parent(dst); | |
| 425 if (src != dst) | |
| 426 sync_parent(src); | |
| 403 } | 427 } |
| 404 return result; | 428 return result; |
| 405 } | 429 } |
| 406 | 430 |
| 407 virtual Status LockFile(const std::string& fname, FileLock** lock) { | 431 virtual Status LockFile(const std::string& fname, FileLock** lock) { |
| 408 *lock = NULL; | 432 *lock = NULL; |
| 409 Status result; | 433 Status result; |
| 410 int flags = ::base::PLATFORM_FILE_OPEN_ALWAYS | | 434 int flags = ::base::PLATFORM_FILE_OPEN_ALWAYS | |
| 411 ::base::PLATFORM_FILE_READ | | 435 ::base::PLATFORM_FILE_READ | |
| 412 ::base::PLATFORM_FILE_WRITE | | 436 ::base::PLATFORM_FILE_WRITE | |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 470 return Status::OK(); | 494 return Status::OK(); |
| 471 } | 495 } |
| 472 | 496 |
| 473 virtual Status NewLogger(const std::string& fname, Logger** result) { | 497 virtual Status NewLogger(const std::string& fname, Logger** result) { |
| 474 FILE* f = fopen_internal(fname.c_str(), "w"); | 498 FILE* f = fopen_internal(fname.c_str(), "w"); |
| 475 if (f == NULL) { | 499 if (f == NULL) { |
| 476 *result = NULL; | 500 *result = NULL; |
| 477 LogToUMA(kNewLogger); | 501 LogToUMA(kNewLogger); |
| 478 return Status::IOError(fname, strerror(errno)); | 502 return Status::IOError(fname, strerror(errno)); |
| 479 } else { | 503 } else { |
| 504 if (!sync_parent(fname)) { | |
| 505 fclose(f); | |
| 506 return Status::IOError(fname, strerror(errno)); | |
| 507 } | |
| 480 *result = new ChromiumLogger(f); | 508 *result = new ChromiumLogger(f); |
| 481 return Status::OK(); | 509 return Status::OK(); |
| 482 } | 510 } |
| 483 } | 511 } |
| 484 | 512 |
| 485 virtual uint64_t NowMicros() { | 513 virtual uint64_t NowMicros() { |
| 486 return ::base::TimeTicks::Now().ToInternalValue(); | 514 return ::base::TimeTicks::Now().ToInternalValue(); |
| 487 } | 515 } |
| 488 | 516 |
| 489 virtual void SleepForMicroseconds(int micros) { | 517 virtual void SleepForMicroseconds(int micros) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 587 ::base::LazyInstance<ChromiumEnv>::Leaky | 615 ::base::LazyInstance<ChromiumEnv>::Leaky |
| 588 default_env = LAZY_INSTANCE_INITIALIZER; | 616 default_env = LAZY_INSTANCE_INITIALIZER; |
| 589 | 617 |
| 590 } | 618 } |
| 591 | 619 |
| 592 Env* Env::Default() { | 620 Env* Env::Default() { |
| 593 return default_env.Pointer(); | 621 return default_env.Pointer(); |
| 594 } | 622 } |
| 595 | 623 |
| 596 } | 624 } |
| OLD | NEW |