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

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

Issue 257003007: Introduce a new framework for back-and-forth tracked/protected preferences migration. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comment nit Created 6 years, 7 months 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') | base/files/important_file_writer_unittest.cc » ('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 #if defined _MSC_VER && _MSC_VER == 1800 5 #if defined _MSC_VER && _MSC_VER == 1800
6 // TODO(scottmg): Internal errors on VS2013 RC in LTCG. This should be removed 6 // TODO(scottmg): Internal errors on VS2013 RC in LTCG. This should be removed
7 // after RTM. http://crbug.com/288948 7 // after RTM. http://crbug.com/288948
8 #pragma optimize("", off) 8 #pragma optimize("", off)
9 #endif 9 #endif
10 10
11 #include "base/files/important_file_writer.h" 11 #include "base/files/important_file_writer.h"
12 12
13 #include <stdio.h> 13 #include <stdio.h>
14 14
15 #include <string> 15 #include <string>
16 16
17 #include "base/bind.h" 17 #include "base/bind.h"
18 #include "base/critical_closure.h" 18 #include "base/critical_closure.h"
19 #include "base/file_util.h" 19 #include "base/file_util.h"
20 #include "base/files/file.h" 20 #include "base/files/file.h"
21 #include "base/files/file_path.h" 21 #include "base/files/file_path.h"
22 #include "base/logging.h" 22 #include "base/logging.h"
23 #include "base/metrics/histogram.h" 23 #include "base/metrics/histogram.h"
24 #include "base/strings/string_number_conversions.h" 24 #include "base/strings/string_number_conversions.h"
25 #include "base/task_runner.h" 25 #include "base/task_runner.h"
26 #include "base/task_runner_util.h"
26 #include "base/threading/thread.h" 27 #include "base/threading/thread.h"
27 #include "base/time/time.h" 28 #include "base/time/time.h"
28 29
29 namespace base { 30 namespace base {
30 31
31 namespace { 32 namespace {
32 33
33 const int kDefaultCommitIntervalMs = 10000; 34 const int kDefaultCommitIntervalMs = 10000;
34 35
35 enum TempFileFailure { 36 enum TempFileFailure {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 87
87 if (!base::ReplaceFile(tmp_file_path, path, NULL)) { 88 if (!base::ReplaceFile(tmp_file_path, path, NULL)) {
88 LogFailure(path, FAILED_RENAMING, "could not rename temporary file"); 89 LogFailure(path, FAILED_RENAMING, "could not rename temporary file");
89 base::DeleteFile(tmp_file_path, false); 90 base::DeleteFile(tmp_file_path, false);
90 return false; 91 return false;
91 } 92 }
92 93
93 return true; 94 return true;
94 } 95 }
95 96
96 ImportantFileWriter::ImportantFileWriter( 97 ImportantFileWriter::ImportantFileWriter(const FilePath& path,
97 const FilePath& path, base::SequencedTaskRunner* task_runner) 98 base::SequencedTaskRunner* task_runner)
98 : path_(path), 99 : path_(path),
99 task_runner_(task_runner), 100 task_runner_(task_runner),
100 serializer_(NULL), 101 serializer_(NULL),
101 commit_interval_(TimeDelta::FromMilliseconds( 102 commit_interval_(TimeDelta::FromMilliseconds(kDefaultCommitIntervalMs)),
102 kDefaultCommitIntervalMs)) { 103 weak_factory_(this) {
103 DCHECK(CalledOnValidThread()); 104 DCHECK(CalledOnValidThread());
104 DCHECK(task_runner_.get()); 105 DCHECK(task_runner_.get());
105 } 106 }
106 107
107 ImportantFileWriter::~ImportantFileWriter() { 108 ImportantFileWriter::~ImportantFileWriter() {
108 // We're usually a member variable of some other object, which also tends 109 // We're usually a member variable of some other object, which also tends
109 // to be our serializer. It may not be safe to call back to the parent object 110 // to be our serializer. It may not be safe to call back to the parent object
110 // being destructed. 111 // being destructed.
111 DCHECK(!HasPendingWrite()); 112 DCHECK(!HasPendingWrite());
112 } 113 }
113 114
114 bool ImportantFileWriter::HasPendingWrite() const { 115 bool ImportantFileWriter::HasPendingWrite() const {
115 DCHECK(CalledOnValidThread()); 116 DCHECK(CalledOnValidThread());
116 return timer_.IsRunning(); 117 return timer_.IsRunning();
117 } 118 }
118 119
119 void ImportantFileWriter::WriteNow(const std::string& data) { 120 void ImportantFileWriter::WriteNow(const std::string& data) {
120 DCHECK(CalledOnValidThread()); 121 DCHECK(CalledOnValidThread());
121 if (data.length() > static_cast<size_t>(kint32max)) { 122 if (data.length() > static_cast<size_t>(kint32max)) {
122 NOTREACHED(); 123 NOTREACHED();
123 return; 124 return;
124 } 125 }
125 126
126 if (HasPendingWrite()) 127 if (HasPendingWrite())
127 timer_.Stop(); 128 timer_.Stop();
128 129
129 if (!task_runner_->PostTask( 130 if (!PostWriteTask(data)) {
130 FROM_HERE,
131 MakeCriticalClosure(
132 Bind(IgnoreResult(&ImportantFileWriter::WriteFileAtomically),
133 path_, data)))) {
134 // Posting the task to background message loop is not expected 131 // Posting the task to background message loop is not expected
135 // to fail, but if it does, avoid losing data and just hit the disk 132 // to fail, but if it does, avoid losing data and just hit the disk
136 // on the current thread. 133 // on the current thread.
137 NOTREACHED(); 134 NOTREACHED();
138 135
139 WriteFileAtomically(path_, data); 136 WriteFileAtomically(path_, data);
140 } 137 }
141 } 138 }
142 139
143 void ImportantFileWriter::ScheduleWrite(DataSerializer* serializer) { 140 void ImportantFileWriter::ScheduleWrite(DataSerializer* serializer) {
(...skipping 13 matching lines...) Expand all
157 std::string data; 154 std::string data;
158 if (serializer_->SerializeData(&data)) { 155 if (serializer_->SerializeData(&data)) {
159 WriteNow(data); 156 WriteNow(data);
160 } else { 157 } else {
161 DLOG(WARNING) << "failed to serialize data to be saved in " 158 DLOG(WARNING) << "failed to serialize data to be saved in "
162 << path_.value().c_str(); 159 << path_.value().c_str();
163 } 160 }
164 serializer_ = NULL; 161 serializer_ = NULL;
165 } 162 }
166 163
164 void ImportantFileWriter::RegisterOnNextSuccessfulWriteCallback(
165 const base::Closure& on_next_successful_write) {
166 DCHECK(on_next_successful_write_.is_null());
167 on_next_successful_write_ = on_next_successful_write;
168 }
169
170 bool ImportantFileWriter::PostWriteTask(const std::string& data) {
171 // TODO(gab): This code could always use PostTaskAndReplyWithResult and let
172 // ForwardSuccessfulWrite() no-op if |on_next_successful_write_| is null, but
173 // PostTaskAndReply causes memory leaks in tests (crbug.com/371974) and
174 // suppressing all of those is unrealistic hence we avoid most of them by
175 // using PostTask() in the typical scenario below.
176 if (!on_next_successful_write_.is_null()) {
177 return base::PostTaskAndReplyWithResult(
178 task_runner_,
179 FROM_HERE,
180 MakeCriticalClosure(
181 Bind(&ImportantFileWriter::WriteFileAtomically, path_, data)),
182 Bind(&ImportantFileWriter::ForwardSuccessfulWrite,
183 weak_factory_.GetWeakPtr()));
184 }
185 return task_runner_->PostTask(
186 FROM_HERE,
187 MakeCriticalClosure(
188 Bind(IgnoreResult(&ImportantFileWriter::WriteFileAtomically),
189 path_, data)));
190 }
191
192 void ImportantFileWriter::ForwardSuccessfulWrite(bool result) {
193 DCHECK(CalledOnValidThread());
194 if (result && !on_next_successful_write_.is_null()) {
195 on_next_successful_write_.Run();
196 on_next_successful_write_.Reset();
197 }
198 }
199
167 } // namespace base 200 } // namespace base
OLDNEW
« no previous file with comments | « base/files/important_file_writer.h ('k') | base/files/important_file_writer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698