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

Side by Side Diff: chrome/browser/chromeos/base/file_flusher.cc

Issue 1815853002: cros: Flush profile files at critical moments (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/base/file_flusher.h"
6
7 #include <set>
8
9 #include "base/bind.h"
10 #include "base/files/file.h"
11 #include "base/files/file_enumerator.h"
12 #include "base/logging.h"
13 #include "base/synchronization/cancellation_flag.h"
14 #include "content/public/browser/browser_thread.h"
15
16 namespace chromeos {
17
18 namespace {
19
20 std::set<base::FilePath> MakeAbsoutePathSet(
21 const base::FilePath& base,
22 const std::vector<base::FilePath>& paths) {
23 std::set<base::FilePath> result;
24 for (const auto& path : paths) {
25 result.insert(path.IsAbsolute() ? path : base.Append(path));
26 }
27 return result;
28 }
29
30 } // namespace
31
32 ////////////////////////////////////////////////////////////////////////////////
33 // FileFlusher::Job
34
35 class FileFlusher::Job {
36 public:
37 Job(const base::WeakPtr<FileFlusher>& master,
38 const base::FilePath& path,
39 const std::vector<base::FilePath>& excludes);
40 ~Job() = default;
41
42 void Start();
43 void Cancel();
44
45 const base::FilePath& path() const { return path_; }
46 bool started() const { return started_; }
47
48 private:
49 void FlushOnBlockingPool();
50 bool ShouldExclude(const base::FilePath& path) const;
51
52 void ScheduleFinishOnUIThread();
achuithb 2016/03/21 17:45:41 Maybe add a comment to say that the Schedule call
xiyuan 2016/03/21 22:14:54 Done.
53 void FinishOnUIThread();
54
55 base::WeakPtr<FileFlusher> master_;
56 const base::FilePath path_;
57 const std::set<base::FilePath> excludes_;
58
59 bool started_ = false;
60 base::CancellationFlag cancel_flag_;
61
62 DISALLOW_COPY_AND_ASSIGN(Job);
63 };
64
65 FileFlusher::Job::Job(const base::WeakPtr<FileFlusher>& master,
66 const base::FilePath& path,
67 const std::vector<base::FilePath>& excludes)
68 : master_(master),
69 path_(path),
70 excludes_(MakeAbsoutePathSet(path, excludes)) {}
71
72 void FileFlusher::Job::Start() {
73 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
74 DCHECK(!started());
75
76 started_ = true;
77
78 if (cancel_flag_.IsSet()) {
79 ScheduleFinishOnUIThread();
80 return;
81 }
82
83 content::BrowserThread::PostBlockingPoolTaskAndReply(
84 FROM_HERE, base::Bind(&FileFlusher::Job::FlushOnBlockingPool,
85 base::Unretained(this)),
86 base::Bind(&FileFlusher::Job::FinishOnUIThread, base::Unretained(this)));
87 }
88
89 void FileFlusher::Job::Cancel() {
90 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
91
92 cancel_flag_.Set();
93
94 // Cancel() could be called in an iterator/range loop in master thus don't
95 // invoke FinishOnUIThread in-place.
96 if (!started())
97 ScheduleFinishOnUIThread();
98 }
99
100 void FileFlusher::Job::FlushOnBlockingPool() {
101 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
102
achuithb 2016/03/21 17:45:41 Would a VLOG(1) logging statement be useful here?
xiyuan 2016/03/21 22:14:54 Done.
103 const bool kRecursive = true;
achuithb 2016/03/21 17:45:41 Is kRecursive appropriate for const stack variable
xiyuan 2016/03/21 22:14:54 Personally prefer to use a const bool instead of u
104 base::FileEnumerator traversal(path_, kRecursive,
105 base::FileEnumerator::FILES);
106 for (base::FilePath current = traversal.Next();
107 !current.empty() && !cancel_flag_.IsSet(); current = traversal.Next()) {
108 if (ShouldExclude(current))
109 continue;
110
111 base::File currentFile(current,
112 base::File::FLAG_OPEN | base::File::FLAG_WRITE);
113 if (!currentFile.IsValid()) {
114 VLOG(1) << "Unable to flush file:" << current.value();
115 continue;
116 }
117
118 currentFile.Flush();
119 currentFile.Close();
120 }
121 }
122
123 bool FileFlusher::Job::ShouldExclude(const base::FilePath& path) const {
124 return excludes_.find(path) != excludes_.end();
125 }
126
127 void FileFlusher::Job::ScheduleFinishOnUIThread() {
128 content::BrowserThread::PostTask(
achuithb 2016/03/21 17:45:41 DCHECK_CURRENTLY_ON(content::BrowserThread::UI)?
xiyuan 2016/03/21 22:14:54 The name is misleading. It schedules "FinishOnUITh
129 content::BrowserThread::UI, FROM_HERE,
130 base::Bind(&FileFlusher::Job::FinishOnUIThread, base::Unretained(this)));
131 }
132
133 void FileFlusher::Job::FinishOnUIThread() {
134 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
135
136 if (master_)
137 master_->OnJobDone(this);
138
139 delete this;
140 }
141
142 ////////////////////////////////////////////////////////////////////////////////
143 // FileFlusher
144
145 FileFlusher::FileFlusher() : weak_factory_(this) {}
146
147 FileFlusher::~FileFlusher() {
148 for (const auto& job : jobs_)
achuithb 2016/03/21 17:45:41 are we allowed to drop {} here?
xiyuan 2016/03/21 22:14:54 Cancel() does not remove it from the vector. It sc
achuithb 2016/03/21 22:32:56 I didn't realize that braces were optional for sin
xiyuan 2016/03/22 18:41:33 I completely mis-understood to comment. :p And ye
149 job->Cancel();
150 }
151
152 void FileFlusher::RequestFlush(const base::FilePath& path,
153 const std::vector<base::FilePath>& excludes) {
154 for (const auto& job : jobs_) {
155 if (path == job->path() || path.IsParent(job->path()))
156 job->Cancel();
157 }
158
159 jobs_.push_back(new Job(weak_factory_.GetWeakPtr(), path, excludes));
160 ScheduleJob();
161 }
162
163 void FileFlusher::ScheduleJob() {
164 if (jobs_.empty())
165 return;
166
167 auto job = jobs_.front();
168 if (!job->started())
169 job->Start();
170 }
171
172 void FileFlusher::OnJobDone(FileFlusher::Job* job) {
173 for (auto it = jobs_.begin(); it != jobs_.end(); ++it) {
achuithb 2016/03/21 17:45:41 for (auto job : jobs_)?
xiyuan 2016/03/21 22:14:54 Need the iterator to remove |job| from |jobs_| so
achuithb 2016/03/21 22:32:56 Acknowledged.
174 if (*it == job) {
175 jobs_.erase(it);
176 break;
177 }
178 }
179
180 ScheduleJob();
181 }
182
183 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/base/file_flusher.h ('k') | chrome/browser/chromeos/chrome_browser_main_chromeos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698