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 |