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

Side by Side Diff: base/files/important_file_writer.cc

Issue 11308196: [cros] RlzValueStore made protected by a cross-process lock and not persisted over browser lifetime… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge Created 8 years 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 | Annotate | Revision Log
« no previous file with comments | « base/files/important_file_writer.h ('k') | chrome/browser/rlz/rlz.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium 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. 3 // found in the LICENSE file.
4 4
5 #include "base/files/important_file_writer.h" 5 #include "base/files/important_file_writer.h"
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 8
9 #include <string> 9 #include <string>
10 10
(...skipping 24 matching lines...) Expand all
35 }; 35 };
36 36
37 void LogFailure(const FilePath& path, TempFileFailure failure_code, 37 void LogFailure(const FilePath& path, TempFileFailure failure_code,
38 const std::string& message) { 38 const std::string& message) {
39 UMA_HISTOGRAM_ENUMERATION("ImportantFile.TempFileFailures", failure_code, 39 UMA_HISTOGRAM_ENUMERATION("ImportantFile.TempFileFailures", failure_code,
40 TEMP_FILE_FAILURE_MAX); 40 TEMP_FILE_FAILURE_MAX);
41 DPLOG(WARNING) << "temp file failure: " << path.value().c_str() 41 DPLOG(WARNING) << "temp file failure: " << path.value().c_str()
42 << " : " << message; 42 << " : " << message;
43 } 43 }
44 44
45 void WriteToDiskTask(const FilePath& path, const std::string& data) { 45 } // namespace
46
47 // static
48 bool ImportantFileWriter::WriteFileAtomically(const FilePath& path,
49 const std::string& data) {
46 // Write the data to a temp file then rename to avoid data loss if we crash 50 // Write the data to a temp file then rename to avoid data loss if we crash
47 // while writing the file. Ensure that the temp file is on the same volume 51 // while writing the file. Ensure that the temp file is on the same volume
48 // as target file, so it can be moved in one step, and that the temp file 52 // as target file, so it can be moved in one step, and that the temp file
49 // is securely created. 53 // is securely created.
50 FilePath tmp_file_path; 54 FilePath tmp_file_path;
51 if (!file_util::CreateTemporaryFileInDir(path.DirName(), &tmp_file_path)) { 55 if (!file_util::CreateTemporaryFileInDir(path.DirName(), &tmp_file_path)) {
52 LogFailure(path, FAILED_CREATING, "could not create temporary file"); 56 LogFailure(path, FAILED_CREATING, "could not create temporary file");
53 return; 57 return false;
54 } 58 }
55 59
56 int flags = PLATFORM_FILE_OPEN | PLATFORM_FILE_WRITE; 60 int flags = PLATFORM_FILE_OPEN | PLATFORM_FILE_WRITE;
57 PlatformFile tmp_file = 61 PlatformFile tmp_file =
58 CreatePlatformFile(tmp_file_path, flags, NULL, NULL); 62 CreatePlatformFile(tmp_file_path, flags, NULL, NULL);
59 if (tmp_file == kInvalidPlatformFileValue) { 63 if (tmp_file == kInvalidPlatformFileValue) {
60 LogFailure(path, FAILED_OPENING, "could not open temporary file"); 64 LogFailure(path, FAILED_OPENING, "could not open temporary file");
61 return; 65 return false;
62 } 66 }
63 67
64 // If this happens in the wild something really bad is going on. 68 // If this happens in the wild something really bad is going on.
65 CHECK_LE(data.length(), static_cast<size_t>(kint32max)); 69 CHECK_LE(data.length(), static_cast<size_t>(kint32max));
66 int bytes_written = WritePlatformFile( 70 int bytes_written = WritePlatformFile(
67 tmp_file, 0, data.data(), static_cast<int>(data.length())); 71 tmp_file, 0, data.data(), static_cast<int>(data.length()));
68 FlushPlatformFile(tmp_file); // Ignore return value. 72 FlushPlatformFile(tmp_file); // Ignore return value.
69 73
70 if (!ClosePlatformFile(tmp_file)) { 74 if (!ClosePlatformFile(tmp_file)) {
71 LogFailure(path, FAILED_CLOSING, "failed to close temporary file"); 75 LogFailure(path, FAILED_CLOSING, "failed to close temporary file");
72 file_util::Delete(tmp_file_path, false); 76 file_util::Delete(tmp_file_path, false);
73 return; 77 return false;
74 } 78 }
75 79
76 if (bytes_written < static_cast<int>(data.length())) { 80 if (bytes_written < static_cast<int>(data.length())) {
77 LogFailure(path, FAILED_WRITING, "error writing, bytes_written=" + 81 LogFailure(path, FAILED_WRITING, "error writing, bytes_written=" +
78 IntToString(bytes_written)); 82 IntToString(bytes_written));
79 file_util::Delete(tmp_file_path, false); 83 file_util::Delete(tmp_file_path, false);
80 return; 84 return false;
81 } 85 }
82 86
83 if (!file_util::ReplaceFile(tmp_file_path, path)) { 87 if (!file_util::ReplaceFile(tmp_file_path, path)) {
84 LogFailure(path, FAILED_RENAMING, "could not rename temporary file"); 88 LogFailure(path, FAILED_RENAMING, "could not rename temporary file");
85 file_util::Delete(tmp_file_path, false); 89 file_util::Delete(tmp_file_path, false);
86 return; 90 return false;
87 } 91 }
92
93 return true;
88 } 94 }
89 95
90 } // namespace
91
92 ImportantFileWriter::ImportantFileWriter( 96 ImportantFileWriter::ImportantFileWriter(
93 const FilePath& path, base::SequencedTaskRunner* task_runner) 97 const FilePath& path, base::SequencedTaskRunner* task_runner)
94 : path_(path), 98 : path_(path),
95 task_runner_(task_runner), 99 task_runner_(task_runner),
96 serializer_(NULL), 100 serializer_(NULL),
97 commit_interval_(TimeDelta::FromMilliseconds( 101 commit_interval_(TimeDelta::FromMilliseconds(
98 kDefaultCommitIntervalMs)) { 102 kDefaultCommitIntervalMs)) {
99 DCHECK(CalledOnValidThread()); 103 DCHECK(CalledOnValidThread());
100 DCHECK(task_runner_.get()); 104 DCHECK(task_runner_.get());
101 } 105 }
(...skipping 13 matching lines...) Expand all
115 void ImportantFileWriter::WriteNow(const std::string& data) { 119 void ImportantFileWriter::WriteNow(const std::string& data) {
116 DCHECK(CalledOnValidThread()); 120 DCHECK(CalledOnValidThread());
117 if (data.length() > static_cast<size_t>(kint32max)) { 121 if (data.length() > static_cast<size_t>(kint32max)) {
118 NOTREACHED(); 122 NOTREACHED();
119 return; 123 return;
120 } 124 }
121 125
122 if (HasPendingWrite()) 126 if (HasPendingWrite())
123 timer_.Stop(); 127 timer_.Stop();
124 128
125 if (!task_runner_->PostTask(FROM_HERE, 129 if (!task_runner_->PostTask(
126 MakeCriticalClosure(Bind(&WriteToDiskTask, path_, data)))) { 130 FROM_HERE,
131 MakeCriticalClosure(
132 Bind(IgnoreResult(&ImportantFileWriter::WriteFileAtomically),
133 path_, data)))) {
127 // Posting the task to background message loop is not expected 134 // Posting the task to background message loop is not expected
128 // to fail, but if it does, avoid losing data and just hit the disk 135 // to fail, but if it does, avoid losing data and just hit the disk
129 // on the current thread. 136 // on the current thread.
130 NOTREACHED(); 137 NOTREACHED();
131 138
132 WriteToDiskTask(path_, data); 139 WriteFileAtomically(path_, data);
133 } 140 }
134 } 141 }
135 142
136 void ImportantFileWriter::ScheduleWrite(DataSerializer* serializer) { 143 void ImportantFileWriter::ScheduleWrite(DataSerializer* serializer) {
137 DCHECK(CalledOnValidThread()); 144 DCHECK(CalledOnValidThread());
138 145
139 DCHECK(serializer); 146 DCHECK(serializer);
140 serializer_ = serializer; 147 serializer_ = serializer;
141 148
142 if (!timer_.IsRunning()) { 149 if (!timer_.IsRunning()) {
143 timer_.Start(FROM_HERE, commit_interval_, this, 150 timer_.Start(FROM_HERE, commit_interval_, this,
144 &ImportantFileWriter::DoScheduledWrite); 151 &ImportantFileWriter::DoScheduledWrite);
145 } 152 }
146 } 153 }
147 154
148 void ImportantFileWriter::DoScheduledWrite() { 155 void ImportantFileWriter::DoScheduledWrite() {
149 DCHECK(serializer_); 156 DCHECK(serializer_);
150 std::string data; 157 std::string data;
151 if (serializer_->SerializeData(&data)) { 158 if (serializer_->SerializeData(&data)) {
152 WriteNow(data); 159 WriteNow(data);
153 } else { 160 } else {
154 DLOG(WARNING) << "failed to serialize data to be saved in " 161 DLOG(WARNING) << "failed to serialize data to be saved in "
155 << path_.value().c_str(); 162 << path_.value().c_str();
156 } 163 }
157 serializer_ = NULL; 164 serializer_ = NULL;
158 } 165 }
159 166
160 } // namespace base 167 } // namespace base
OLDNEW
« no previous file with comments | « base/files/important_file_writer.h ('k') | chrome/browser/rlz/rlz.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698