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 12 matching lines...) Expand all Loading... | |
| 23 #include "leveldb/env.h" | 23 #include "leveldb/env.h" |
| 24 #include "leveldb/slice.h" | 24 #include "leveldb/slice.h" |
| 25 #include "port/port.h" | 25 #include "port/port.h" |
| 26 #include "util/logging.h" | 26 #include "util/logging.h" |
| 27 | 27 |
| 28 #if defined(OS_WIN) | 28 #if defined(OS_WIN) |
| 29 #include <io.h> | 29 #include <io.h> |
| 30 #include "base/win/win_util.h" | 30 #include "base/win/win_util.h" |
| 31 #endif | 31 #endif |
| 32 | 32 |
| 33 #if !defined(OS_WIN) | |
| 34 #include <fcntl.h> | |
|
dgrogan
2012/12/06 23:17:38
Oh yeah, what's this for?
ericu
2012/12/10 18:31:12
O_WRONLY
| |
| 35 #endif | |
| 36 | |
| 33 namespace { | 37 namespace { |
| 34 | 38 |
| 35 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID) || \ | 39 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID) || \ |
| 36 defined(OS_OPENBSD) | 40 defined(OS_OPENBSD) |
| 37 // The following are glibc-specific | 41 // The following are glibc-specific |
| 38 | 42 |
| 39 size_t fread_unlocked(void *ptr, size_t size, size_t n, FILE *file) { | 43 size_t fread_unlocked(void *ptr, size_t size, size_t n, FILE *file) { |
| 40 return fread(ptr, size, n, file); | 44 return fread(ptr, size, n, file); |
| 41 } | 45 } |
| 42 | 46 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 59 #endif | 63 #endif |
| 60 | 64 |
| 61 #endif | 65 #endif |
| 62 | 66 |
| 63 // Wide-char safe fopen wrapper. | 67 // Wide-char safe fopen wrapper. |
| 64 FILE* fopen_internal(const char* fname, const char* mode) { | 68 FILE* fopen_internal(const char* fname, const char* mode) { |
| 65 #if defined(OS_WIN) | 69 #if defined(OS_WIN) |
| 66 return _wfopen(UTF8ToUTF16(fname).c_str(), ASCIIToUTF16(mode).c_str()); | 70 return _wfopen(UTF8ToUTF16(fname).c_str(), ASCIIToUTF16(mode).c_str()); |
| 67 #else | 71 #else |
| 68 return fopen(fname, mode); | 72 return fopen(fname, mode); |
| 73 } | |
|
dgrogan
2012/12/06 23:15:41
This won't compile on windows, will it?
ericu
2012/12/10 18:31:12
Fixed. However, I'm having trouble uploading a ne
dgrogan
2012/12/10 21:53:46
Editing it here should work, env_chromium.cc lives
| |
| 69 #endif | 74 #endif |
| 70 } | |
| 71 | |
| 72 } // namespace | |
| 73 | |
| 74 namespace leveldb { | |
| 75 | |
| 76 namespace { | |
| 77 | |
| 78 class Thread; | |
| 79 | |
| 80 static const ::FilePath::CharType kLevelDBTestDirectoryPrefix[] | |
| 81 = FILE_PATH_LITERAL("leveldb-test-"); | |
| 82 | 75 |
| 83 ::FilePath CreateFilePath(const std::string& file_path) { | 76 ::FilePath CreateFilePath(const std::string& file_path) { |
| 84 #if defined(OS_WIN) | 77 #if defined(OS_WIN) |
| 85 return FilePath(UTF8ToUTF16(file_path)); | 78 return FilePath(UTF8ToUTF16(file_path)); |
| 86 #else | 79 #else |
| 87 return FilePath(file_path); | 80 return FilePath(file_path); |
| 88 #endif | 81 #endif |
| 89 } | 82 } |
| 90 | 83 |
| 91 std::string FilePathToString(const ::FilePath& file_path) { | 84 std::string FilePathToString(const ::FilePath& file_path) { |
| 92 #if defined(OS_WIN) | 85 #if defined(OS_WIN) |
| 93 return UTF16ToUTF8(file_path.value()); | 86 return UTF16ToUTF8(file_path.value()); |
| 94 #else | 87 #else |
| 95 return file_path.value(); | 88 return file_path.value(); |
| 96 #endif | 89 #endif |
| 97 } | 90 } |
| 98 | 91 |
| 92 bool sync_parent(const std::string& fname) { | |
| 93 #if !defined(OS_WIN) | |
| 94 FilePath parent_dir = CreateFilePath(fname).DirName(); | |
| 95 int parent_fd = open(FilePathToString(parent_dir).c_str(), O_WRONLY); | |
| 96 if (parent_fd < 0) | |
| 97 return false; | |
| 98 fsync(parent_fd); | |
| 99 close(parent_fd); | |
| 100 #endif | |
| 101 return true; | |
| 102 } | |
| 103 | |
| 104 } // namespace | |
| 105 | |
| 106 namespace leveldb { | |
| 107 | |
| 108 namespace { | |
| 109 | |
| 110 class Thread; | |
| 111 | |
| 112 static const ::FilePath::CharType kLevelDBTestDirectoryPrefix[] | |
| 113 = FILE_PATH_LITERAL("leveldb-test-"); | |
| 114 | |
| 99 // TODO(jorlow): This should be moved into Chromium's base. | 115 // TODO(jorlow): This should be moved into Chromium's base. |
| 100 const char* PlatformFileErrorString(const ::base::PlatformFileError& error) { | 116 const char* PlatformFileErrorString(const ::base::PlatformFileError& error) { |
| 101 switch (error) { | 117 switch (error) { |
| 102 case ::base::PLATFORM_FILE_ERROR_FAILED: | 118 case ::base::PLATFORM_FILE_ERROR_FAILED: |
| 103 return "Opening file failed."; | 119 return "Opening file failed."; |
| 104 case ::base::PLATFORM_FILE_ERROR_IN_USE: | 120 case ::base::PLATFORM_FILE_ERROR_IN_USE: |
| 105 return "File currently in use."; | 121 return "File currently in use."; |
| 106 case ::base::PLATFORM_FILE_ERROR_EXISTS: | 122 case ::base::PLATFORM_FILE_ERROR_EXISTS: |
| 107 return "File already exists."; | 123 return "File already exists."; |
| 108 case ::base::PLATFORM_FILE_ERROR_NOT_FOUND: | 124 case ::base::PLATFORM_FILE_ERROR_NOT_FOUND: |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 283 return Status::OK(); | 299 return Status::OK(); |
| 284 } | 300 } |
| 285 | 301 |
| 286 virtual Status NewWritableFile(const std::string& fname, | 302 virtual Status NewWritableFile(const std::string& fname, |
| 287 WritableFile** result) { | 303 WritableFile** result) { |
| 288 *result = NULL; | 304 *result = NULL; |
| 289 FILE* f = fopen_internal(fname.c_str(), "wb"); | 305 FILE* f = fopen_internal(fname.c_str(), "wb"); |
| 290 if (f == NULL) { | 306 if (f == NULL) { |
| 291 return Status::IOError(fname, strerror(errno)); | 307 return Status::IOError(fname, strerror(errno)); |
| 292 } else { | 308 } else { |
| 309 if (!sync_parent(fname)) { | |
| 310 fclose(f); | |
| 311 return Status::IOError(fname, strerror(errno)); | |
| 312 } | |
| 293 *result = new ChromiumWritableFile(fname, f); | 313 *result = new ChromiumWritableFile(fname, f); |
| 294 return Status::OK(); | 314 return Status::OK(); |
| 295 } | 315 } |
| 296 } | 316 } |
| 297 | 317 |
| 298 virtual bool FileExists(const std::string& fname) { | 318 virtual bool FileExists(const std::string& fname) { |
| 299 return ::file_util::PathExists(CreateFilePath(fname)); | 319 return ::file_util::PathExists(CreateFilePath(fname)); |
| 300 } | 320 } |
| 301 | 321 |
| 302 virtual Status GetChildren(const std::string& dir, | 322 virtual Status GetChildren(const std::string& dir, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 } else { | 370 } else { |
| 351 *size = static_cast<uint64_t>(signed_size); | 371 *size = static_cast<uint64_t>(signed_size); |
| 352 } | 372 } |
| 353 return s; | 373 return s; |
| 354 } | 374 } |
| 355 | 375 |
| 356 virtual Status RenameFile(const std::string& src, const std::string& dst) { | 376 virtual Status RenameFile(const std::string& src, const std::string& dst) { |
| 357 Status result; | 377 Status result; |
| 358 if (!::file_util::ReplaceFile(CreateFilePath(src), CreateFilePath(dst))) { | 378 if (!::file_util::ReplaceFile(CreateFilePath(src), CreateFilePath(dst))) { |
| 359 result = Status::IOError(src, "Could not rename file."); | 379 result = Status::IOError(src, "Could not rename file."); |
| 380 } else { | |
| 381 sync_parent(dst); | |
|
dgrogan
2012/12/06 23:15:41
Was ignoring the return value an oversight or cons
ericu
2012/12/10 18:31:12
Conscious choice. There's nothing we can do about
| |
| 382 if (src != dst) | |
| 383 sync_parent(src); | |
| 360 } | 384 } |
| 361 return result; | 385 return result; |
| 362 } | 386 } |
| 363 | 387 |
| 364 virtual Status LockFile(const std::string& fname, FileLock** lock) { | 388 virtual Status LockFile(const std::string& fname, FileLock** lock) { |
| 365 *lock = NULL; | 389 *lock = NULL; |
| 366 Status result; | 390 Status result; |
| 367 int flags = ::base::PLATFORM_FILE_OPEN_ALWAYS | | 391 int flags = ::base::PLATFORM_FILE_OPEN_ALWAYS | |
| 368 ::base::PLATFORM_FILE_READ | | 392 ::base::PLATFORM_FILE_READ | |
| 369 ::base::PLATFORM_FILE_WRITE | | 393 ::base::PLATFORM_FILE_WRITE | |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 mu_.Release(); | 447 mu_.Release(); |
| 424 return Status::OK(); | 448 return Status::OK(); |
| 425 } | 449 } |
| 426 | 450 |
| 427 virtual Status NewLogger(const std::string& fname, Logger** result) { | 451 virtual Status NewLogger(const std::string& fname, Logger** result) { |
| 428 FILE* f = fopen_internal(fname.c_str(), "w"); | 452 FILE* f = fopen_internal(fname.c_str(), "w"); |
| 429 if (f == NULL) { | 453 if (f == NULL) { |
| 430 *result = NULL; | 454 *result = NULL; |
| 431 return Status::IOError(fname, strerror(errno)); | 455 return Status::IOError(fname, strerror(errno)); |
| 432 } else { | 456 } else { |
| 457 if (!sync_parent(fname)) { | |
| 458 fclose(f); | |
| 459 return Status::IOError(fname, strerror(errno)); | |
| 460 } | |
| 433 *result = new ChromiumLogger(f); | 461 *result = new ChromiumLogger(f); |
| 434 return Status::OK(); | 462 return Status::OK(); |
| 435 } | 463 } |
| 436 } | 464 } |
| 437 | 465 |
| 438 virtual uint64_t NowMicros() { | 466 virtual uint64_t NowMicros() { |
| 439 return ::base::TimeTicks::Now().ToInternalValue(); | 467 return ::base::TimeTicks::Now().ToInternalValue(); |
| 440 } | 468 } |
| 441 | 469 |
| 442 virtual void SleepForMicroseconds(int micros) { | 470 virtual void SleepForMicroseconds(int micros) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 540 ::base::LazyInstance<ChromiumEnv>::Leaky | 568 ::base::LazyInstance<ChromiumEnv>::Leaky |
| 541 default_env = LAZY_INSTANCE_INITIALIZER; | 569 default_env = LAZY_INSTANCE_INITIALIZER; |
| 542 | 570 |
| 543 } | 571 } |
| 544 | 572 |
| 545 Env* Env::Default() { | 573 Env* Env::Default() { |
| 546 return default_env.Pointer(); | 574 return default_env.Pointer(); |
| 547 } | 575 } |
| 548 | 576 |
| 549 } | 577 } |
| OLD | NEW |