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

Side by Side Diff: components/history/core/browser/history_backend.cc

Issue 2672753002: Refactor History's CommitLaterTask with CancelableCallback (Closed)
Patch Set: Explicitly close TestHistoryBackend. Created 3 years, 10 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "components/history/core/browser/history_backend.h" 5 #include "components/history/core/browser/history_backend.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 #include <list> 9 #include <list>
10 #include <map> 10 #include <map>
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } else { 107 } else {
108 mv.redirects = redirects; 108 mv.redirects = redirects;
109 if (mv.redirects.back() != mv.url) { 109 if (mv.redirects.back() != mv.url) {
110 // The last url must be the target url. 110 // The last url must be the target url.
111 mv.redirects.push_back(mv.url); 111 mv.redirects.push_back(mv.url);
112 } 112 }
113 } 113 }
114 return mv; 114 return mv;
115 } 115 }
116 116
117 // This task is run on a timer so that commits happen at regular intervals
118 // so they are batched together. The important thing about this class is that
119 // it supports canceling of the task so the reference to the backend will be
120 // freed. The problem is that when history is shutting down, there is likely
121 // to be one of these commits still pending and holding a reference.
122 //
123 // The backend can call Cancel to have this task release the reference. The
124 // task will still run (if we ever get to processing the event before
125 // shutdown), but it will not do anything.
126 //
127 // Note that this is a refcounted object and is not a task in itself. It should
128 // be assigned to a RunnableMethod.
129 //
130 // TODO(brettw): bug 1165182: This should be replaced with a
131 // base::WeakPtrFactory which will handle everything automatically (like we do
132 // in ExpireHistoryBackend).
133 class CommitLaterTask : public base::RefCounted<CommitLaterTask> {
134 public:
135 explicit CommitLaterTask(HistoryBackend* history_backend)
136 : history_backend_(history_backend) {}
137
138 // The backend will call this function if it is being destroyed so that we
139 // release our reference.
140 void Cancel() { history_backend_ = nullptr; }
141
142 void RunCommit() {
143 if (history_backend_)
144 history_backend_->Commit();
145 }
146
147 private:
148 friend class base::RefCounted<CommitLaterTask>;
149
150 ~CommitLaterTask() {}
151
152 scoped_refptr<HistoryBackend> history_backend_;
153 };
154
155 QueuedHistoryDBTask::QueuedHistoryDBTask( 117 QueuedHistoryDBTask::QueuedHistoryDBTask(
156 std::unique_ptr<HistoryDBTask> task, 118 std::unique_ptr<HistoryDBTask> task,
157 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, 119 scoped_refptr<base::SingleThreadTaskRunner> origin_loop,
158 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) 120 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled)
159 : task_(std::move(task)), 121 : task_(std::move(task)),
160 origin_loop_(origin_loop), 122 origin_loop_(origin_loop),
161 is_canceled_(is_canceled) { 123 is_canceled_(is_canceled) {
162 DCHECK(task_); 124 DCHECK(task_);
163 DCHECK(origin_loop_); 125 DCHECK(origin_loop_);
164 DCHECK(!is_canceled_.is_null()); 126 DCHECK(!is_canceled_.is_null());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 scoped_refptr<base::SequencedTaskRunner> task_runner) 172 scoped_refptr<base::SequencedTaskRunner> task_runner)
211 : delegate_(delegate), 173 : delegate_(delegate),
212 scheduled_kill_db_(false), 174 scheduled_kill_db_(false),
213 expirer_(this, backend_client.get(), task_runner), 175 expirer_(this, backend_client.get(), task_runner),
214 recent_redirects_(kMaxRedirectCount), 176 recent_redirects_(kMaxRedirectCount),
215 segment_queried_(false), 177 segment_queried_(false),
216 backend_client_(std::move(backend_client)), 178 backend_client_(std::move(backend_client)),
217 task_runner_(task_runner) {} 179 task_runner_(task_runner) {}
218 180
219 HistoryBackend::~HistoryBackend() { 181 HistoryBackend::~HistoryBackend() {
220 DCHECK(!scheduled_commit_) << "Deleting without cleanup"; 182 DCHECK(scheduled_commit_.IsCancelled()) << "Deleting without cleanup";
221 queued_history_db_tasks_.clear(); 183 queued_history_db_tasks_.clear();
222 184
223 // Release stashed embedder object before cleaning up the databases. 185 // Release stashed embedder object before cleaning up the databases.
224 supports_user_data_helper_.reset(); 186 supports_user_data_helper_.reset();
225 187
226 // First close the databases before optionally running the "destroy" task. 188 // First close the databases before optionally running the "destroy" task.
227 CloseAllDatabases(); 189 CloseAllDatabases();
228 190
229 if (!backend_destroy_task_.is_null()) { 191 if (!backend_destroy_task_.is_null()) {
230 // Notify an interested party (typically a unit test) that we're done. 192 // Notify an interested party (typically a unit test) that we're done.
(...skipping 2004 matching lines...) Expand 10 before | Expand all | Expand 10 after
2235 2197
2236 if (thumbnail_db_) { 2198 if (thumbnail_db_) {
2237 thumbnail_db_->CommitTransaction(); 2199 thumbnail_db_->CommitTransaction();
2238 DCHECK_EQ(thumbnail_db_->transaction_nesting(), 0) 2200 DCHECK_EQ(thumbnail_db_->transaction_nesting(), 0)
2239 << "Somebody left a transaction open"; 2201 << "Somebody left a transaction open";
2240 thumbnail_db_->BeginTransaction(); 2202 thumbnail_db_->BeginTransaction();
2241 } 2203 }
2242 } 2204 }
2243 2205
2244 void HistoryBackend::ScheduleCommit() { 2206 void HistoryBackend::ScheduleCommit() {
2245 if (scheduled_commit_) 2207 // Non-cancelled means there's an already scheduled commit. Note that
2208 // CancelableClosure starts cancelled with the default constructor.
2209 if (!scheduled_commit_.IsCancelled())
2246 return; 2210 return;
2247 scheduled_commit_ = new CommitLaterTask(this); 2211
2212 scheduled_commit_.Reset(
2213 base::Bind(&HistoryBackend::Commit, base::Unretained(this)));
2214
2248 task_runner_->PostDelayedTask( 2215 task_runner_->PostDelayedTask(
2249 FROM_HERE, 2216 FROM_HERE, scheduled_commit_.callback(),
2250 base::Bind(&CommitLaterTask::RunCommit, scheduled_commit_),
2251 base::TimeDelta::FromSeconds(kCommitIntervalSeconds)); 2217 base::TimeDelta::FromSeconds(kCommitIntervalSeconds));
2252 } 2218 }
2253 2219
2254 void HistoryBackend::CancelScheduledCommit() { 2220 void HistoryBackend::CancelScheduledCommit() {
2255 if (scheduled_commit_) { 2221 scheduled_commit_.Cancel();
2256 scheduled_commit_->Cancel();
2257 scheduled_commit_ = nullptr;
2258 }
2259 } 2222 }
2260 2223
2261 void HistoryBackend::ProcessDBTaskImpl() { 2224 void HistoryBackend::ProcessDBTaskImpl() {
2262 if (!db_) { 2225 if (!db_) {
2263 // db went away, release all the refs. 2226 // db went away, release all the refs.
2264 queued_history_db_tasks_.clear(); 2227 queued_history_db_tasks_.clear();
2265 return; 2228 return;
2266 } 2229 }
2267 2230
2268 // Remove any canceled tasks. 2231 // Remove any canceled tasks.
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
2646 // transaction is currently open. 2609 // transaction is currently open.
2647 db_->CommitTransaction(); 2610 db_->CommitTransaction();
2648 db_->Vacuum(); 2611 db_->Vacuum();
2649 db_->BeginTransaction(); 2612 db_->BeginTransaction();
2650 db_->GetStartDate(&first_recorded_time_); 2613 db_->GetStartDate(&first_recorded_time_);
2651 2614
2652 return true; 2615 return true;
2653 } 2616 }
2654 2617
2655 } // namespace history 2618 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698