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

Side by Side Diff: chrome/browser/history/history_backend.cc

Issue 387923002: Make HistoryDBTask not refcounted, and ensure it's destroyed on its origin thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 6 years, 5 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
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 "chrome/browser/history/history_backend.h" 5 #include "chrome/browser/history/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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 } 156 }
157 157
158 private: 158 private:
159 friend class base::RefCounted<CommitLaterTask>; 159 friend class base::RefCounted<CommitLaterTask>;
160 160
161 ~CommitLaterTask() {} 161 ~CommitLaterTask() {}
162 162
163 scoped_refptr<HistoryBackend> history_backend_; 163 scoped_refptr<HistoryBackend> history_backend_;
164 }; 164 };
165 165
166 // QueuedHistoryDBTask ---------------------------------------------------------
167 166
168 QueuedHistoryDBTask::QueuedHistoryDBTask( 167 QueuedHistoryDBTask::QueuedHistoryDBTask(
169 scoped_refptr<HistoryDBTask> task, 168 scoped_ptr<HistoryDBTask> task,
170 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, 169 scoped_refptr<base::SingleThreadTaskRunner> origin_loop,
171 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) 170 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled)
172 : task_(task), origin_loop_(origin_loop), is_canceled_(is_canceled) { 171 : task_(task.Pass()), origin_loop_(origin_loop), is_canceled_(is_canceled) {
173 DCHECK(task_); 172 DCHECK(task_);
174 DCHECK(origin_loop_); 173 DCHECK(origin_loop_);
175 DCHECK(!is_canceled_.is_null()); 174 DCHECK(!is_canceled_.is_null());
176 } 175 }
177 176
178 QueuedHistoryDBTask::~QueuedHistoryDBTask() { 177 QueuedHistoryDBTask::~QueuedHistoryDBTask() {
178 origin_loop_->PostTask(
sky 2014/07/14 20:27:44 Document why this is done.
Bernhard Bauer 2014/07/15 10:17:24 Done.
179 FROM_HERE,
180 base::Bind(&base::DeletePointer<HistoryDBTask>,
181 base::Unretained(task_.release())));
179 } 182 }
180 183
181 bool QueuedHistoryDBTask::is_canceled() { 184 bool QueuedHistoryDBTask::is_canceled() {
182 return is_canceled_.Run(); 185 return is_canceled_.Run();
183 } 186 }
184 187
185 bool QueuedHistoryDBTask::RunOnDBThread(HistoryBackend* backend, 188 bool QueuedHistoryDBTask::Run(HistoryBackend* backend,
186 HistoryDatabase* db) { 189 HistoryDatabase* db) {
187 return task_->RunOnDBThread(backend, db); 190 return task_->RunOnDBThread(backend, db);
188 } 191 }
189 192
190 void QueuedHistoryDBTask::DoneRunOnMainThread() { 193 void QueuedHistoryDBTask::DoneRun() {
191 origin_loop_->PostTask( 194 origin_loop_->PostTask(
192 FROM_HERE, 195 FROM_HERE,
193 base::Bind(&RunUnlessCanceled, 196 base::Bind(&RunUnlessCanceled,
194 base::Bind(&HistoryDBTask::DoneRunOnMainThread, task_), 197 base::Bind(&HistoryDBTask::DoneRunOnMainThread,
198 base::Unretained(task_.get())),
195 is_canceled_)); 199 is_canceled_));
196 } 200 }
197 201
198 // HistoryBackend -------------------------------------------------------------- 202 // HistoryBackend --------------------------------------------------------------
199 203
200 HistoryBackend::HistoryBackend(const base::FilePath& history_dir, 204 HistoryBackend::HistoryBackend(const base::FilePath& history_dir,
201 Delegate* delegate, 205 Delegate* delegate,
202 HistoryClient* history_client) 206 HistoryClient* history_client)
203 : delegate_(delegate), 207 : delegate_(delegate),
204 history_dir_(history_dir), 208 history_dir_(history_dir),
205 scheduled_kill_db_(false), 209 scheduled_kill_db_(false),
206 expirer_(this, history_client), 210 expirer_(this, history_client),
207 recent_redirects_(kMaxRedirectCount), 211 recent_redirects_(kMaxRedirectCount),
208 backend_destroy_message_loop_(NULL), 212 backend_destroy_message_loop_(NULL),
209 segment_queried_(false), 213 segment_queried_(false),
210 history_client_(history_client) { 214 history_client_(history_client) {
211 } 215 }
212 216
213 HistoryBackend::~HistoryBackend() { 217 HistoryBackend::~HistoryBackend() {
214 DCHECK(!scheduled_commit_.get()) << "Deleting without cleanup"; 218 DCHECK(!scheduled_commit_.get()) << "Deleting without cleanup";
219 STLDeleteContainerPointers(queued_history_db_tasks_.begin(),
sky 2014/07/14 20:27:44 Should we post to the main thread here?
Bernhard Bauer 2014/07/15 10:17:24 No, QueuedHistoryTask lives fully on the DB thread
220 queued_history_db_tasks_.end());
215 queued_history_db_tasks_.clear(); 221 queued_history_db_tasks_.clear();
216 222
217 #if defined(OS_ANDROID) 223 #if defined(OS_ANDROID)
218 // Release AndroidProviderBackend before other objects. 224 // Release AndroidProviderBackend before other objects.
219 android_provider_backend_.reset(); 225 android_provider_backend_.reset();
220 #endif 226 #endif
221 227
222 // First close the databases before optionally running the "destroy" task. 228 // First close the databases before optionally running the "destroy" task.
223 CloseAllDatabases(); 229 CloseAllDatabases();
224 230
(...skipping 2095 matching lines...) Expand 10 before | Expand all | Expand 10 after
2320 void HistoryBackend::CancelScheduledCommit() { 2326 void HistoryBackend::CancelScheduledCommit() {
2321 if (scheduled_commit_.get()) { 2327 if (scheduled_commit_.get()) {
2322 scheduled_commit_->Cancel(); 2328 scheduled_commit_->Cancel();
2323 scheduled_commit_ = NULL; 2329 scheduled_commit_ = NULL;
2324 } 2330 }
2325 } 2331 }
2326 2332
2327 void HistoryBackend::ProcessDBTaskImpl() { 2333 void HistoryBackend::ProcessDBTaskImpl() {
2328 if (!db_) { 2334 if (!db_) {
2329 // db went away, release all the refs. 2335 // db went away, release all the refs.
2336 STLDeleteContainerPointers(queued_history_db_tasks_.begin(),
2337 queued_history_db_tasks_.end());
2330 queued_history_db_tasks_.clear(); 2338 queued_history_db_tasks_.clear();
2331 return; 2339 return;
2332 } 2340 }
2333 2341
2334 // Remove any canceled tasks. 2342 // Remove any canceled tasks.
2335 while (!queued_history_db_tasks_.empty()) { 2343 while (!queued_history_db_tasks_.empty()) {
2336 QueuedHistoryDBTask& task = queued_history_db_tasks_.front(); 2344 QueuedHistoryDBTask* task = queued_history_db_tasks_.front();
2337 if (!task.is_canceled()) { 2345 if (!task->is_canceled())
2338 break; 2346 break;
2339 } 2347
2348 delete task;
2340 queued_history_db_tasks_.pop_front(); 2349 queued_history_db_tasks_.pop_front();
2341 } 2350 }
2342 if (queued_history_db_tasks_.empty()) 2351 if (queued_history_db_tasks_.empty())
2343 return; 2352 return;
2344 2353
2345 // Run the first task. 2354 // Run the first task.
2346 QueuedHistoryDBTask task = queued_history_db_tasks_.front(); 2355 scoped_ptr<QueuedHistoryDBTask> task(queued_history_db_tasks_.front());
2347 queued_history_db_tasks_.pop_front(); 2356 queued_history_db_tasks_.pop_front();
2348 if (task.RunOnDBThread(this, db_.get())) { 2357 if (task->Run(this, db_.get())) {
2349 // The task is done, notify the callback. 2358 // The task is done, notify the callback.
2350 task.DoneRunOnMainThread(); 2359 task->DoneRun();
2351 } else { 2360 } else {
2352 // The task wants to run some more. Schedule it at the end of the current 2361 // The task wants to run some more. Schedule it at the end of the current
2353 // tasks, and process it after an invoke later. 2362 // tasks, and process it after an invoke later.
2354 queued_history_db_tasks_.insert(queued_history_db_tasks_.end(), task); 2363 queued_history_db_tasks_.push_back(task.release());
2355 base::MessageLoop::current()->PostTask( 2364 base::MessageLoop::current()->PostTask(
2356 FROM_HERE, base::Bind(&HistoryBackend::ProcessDBTaskImpl, this)); 2365 FROM_HERE, base::Bind(&HistoryBackend::ProcessDBTaskImpl, this));
2357 } 2366 }
2358 } 2367 }
2359 2368
2360 //////////////////////////////////////////////////////////////////////////////// 2369 ////////////////////////////////////////////////////////////////////////////////
2361 // 2370 //
2362 // Generic operations 2371 // Generic operations
2363 // 2372 //
2364 //////////////////////////////////////////////////////////////////////////////// 2373 ////////////////////////////////////////////////////////////////////////////////
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
2530 // The expirer keeps tabs on the active databases. Tell it about the 2539 // The expirer keeps tabs on the active databases. Tell it about the
2531 // databases which will be closed. 2540 // databases which will be closed.
2532 expirer_.SetDatabases(NULL, NULL); 2541 expirer_.SetDatabases(NULL, NULL);
2533 2542
2534 // Reopen a new transaction for |db_| for the sake of CloseAllDatabases(). 2543 // Reopen a new transaction for |db_| for the sake of CloseAllDatabases().
2535 db_->BeginTransaction(); 2544 db_->BeginTransaction();
2536 CloseAllDatabases(); 2545 CloseAllDatabases();
2537 } 2546 }
2538 2547
2539 void HistoryBackend::ProcessDBTask( 2548 void HistoryBackend::ProcessDBTask(
2540 scoped_refptr<HistoryDBTask> task, 2549 scoped_ptr<HistoryDBTask> task,
2541 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, 2550 scoped_refptr<base::SingleThreadTaskRunner> origin_loop,
2542 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { 2551 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) {
2543 bool scheduled = !queued_history_db_tasks_.empty(); 2552 bool scheduled = !queued_history_db_tasks_.empty();
2544 queued_history_db_tasks_.insert( 2553 queued_history_db_tasks_.push_back(
2545 queued_history_db_tasks_.end(), 2554 new QueuedHistoryDBTask(task.Pass(), origin_loop, is_canceled));
2546 QueuedHistoryDBTask(task, origin_loop, is_canceled));
2547 if (!scheduled) 2555 if (!scheduled)
2548 ProcessDBTaskImpl(); 2556 ProcessDBTaskImpl();
2549 } 2557 }
2550 2558
2551 void HistoryBackend::BroadcastNotifications( 2559 void HistoryBackend::BroadcastNotifications(
2552 int type, 2560 int type,
2553 scoped_ptr<HistoryDetails> details) { 2561 scoped_ptr<HistoryDetails> details) {
2554 // |delegate_| may be NULL if |this| is in the process of closing (closed by 2562 // |delegate_| may be NULL if |this| is in the process of closing (closed by
2555 // HistoryService -> HistoryBackend::Closing(). 2563 // HistoryService -> HistoryBackend::Closing().
2556 if (delegate_) 2564 if (delegate_)
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
2741 int rank = kPageVisitStatsMaxTopSites; 2749 int rank = kPageVisitStatsMaxTopSites;
2742 std::map<GURL, int>::const_iterator it = most_visited_urls_map_.find(url); 2750 std::map<GURL, int>::const_iterator it = most_visited_urls_map_.find(url);
2743 if (it != most_visited_urls_map_.end()) 2751 if (it != most_visited_urls_map_.end())
2744 rank = (*it).second; 2752 rank = (*it).second;
2745 UMA_HISTOGRAM_ENUMERATION("History.TopSitesVisitsByRank", 2753 UMA_HISTOGRAM_ENUMERATION("History.TopSitesVisitsByRank",
2746 rank, kPageVisitStatsMaxTopSites + 1); 2754 rank, kPageVisitStatsMaxTopSites + 1);
2747 } 2755 }
2748 #endif 2756 #endif
2749 2757
2750 } // namespace history 2758 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698