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 |