OLD | NEW |
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 Loading... |
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 // Ensure that |task_| is destroyed on its origin thread. |
| 179 origin_loop_->PostTask( |
| 180 FROM_HERE, |
| 181 base::Bind(&base::DeletePointer<HistoryDBTask>, |
| 182 base::Unretained(task_.release()))); |
179 } | 183 } |
180 | 184 |
181 bool QueuedHistoryDBTask::is_canceled() { | 185 bool QueuedHistoryDBTask::is_canceled() { |
182 return is_canceled_.Run(); | 186 return is_canceled_.Run(); |
183 } | 187 } |
184 | 188 |
185 bool QueuedHistoryDBTask::RunOnDBThread(HistoryBackend* backend, | 189 bool QueuedHistoryDBTask::Run(HistoryBackend* backend, |
186 HistoryDatabase* db) { | 190 HistoryDatabase* db) { |
187 return task_->RunOnDBThread(backend, db); | 191 return task_->RunOnDBThread(backend, db); |
188 } | 192 } |
189 | 193 |
190 void QueuedHistoryDBTask::DoneRunOnMainThread() { | 194 void QueuedHistoryDBTask::DoneRun() { |
191 origin_loop_->PostTask( | 195 origin_loop_->PostTask( |
192 FROM_HERE, | 196 FROM_HERE, |
193 base::Bind(&RunUnlessCanceled, | 197 base::Bind(&RunUnlessCanceled, |
194 base::Bind(&HistoryDBTask::DoneRunOnMainThread, task_), | 198 base::Bind(&HistoryDBTask::DoneRunOnMainThread, |
| 199 base::Unretained(task_.get())), |
195 is_canceled_)); | 200 is_canceled_)); |
196 } | 201 } |
197 | 202 |
198 // HistoryBackend -------------------------------------------------------------- | 203 // HistoryBackend -------------------------------------------------------------- |
199 | 204 |
200 HistoryBackend::HistoryBackend(const base::FilePath& history_dir, | 205 HistoryBackend::HistoryBackend(const base::FilePath& history_dir, |
201 Delegate* delegate, | 206 Delegate* delegate, |
202 HistoryClient* history_client) | 207 HistoryClient* history_client) |
203 : delegate_(delegate), | 208 : delegate_(delegate), |
204 history_dir_(history_dir), | 209 history_dir_(history_dir), |
205 scheduled_kill_db_(false), | 210 scheduled_kill_db_(false), |
206 expirer_(this, history_client), | 211 expirer_(this, history_client), |
207 recent_redirects_(kMaxRedirectCount), | 212 recent_redirects_(kMaxRedirectCount), |
208 backend_destroy_message_loop_(NULL), | 213 backend_destroy_message_loop_(NULL), |
209 segment_queried_(false), | 214 segment_queried_(false), |
210 history_client_(history_client) { | 215 history_client_(history_client) { |
211 } | 216 } |
212 | 217 |
213 HistoryBackend::~HistoryBackend() { | 218 HistoryBackend::~HistoryBackend() { |
214 DCHECK(!scheduled_commit_.get()) << "Deleting without cleanup"; | 219 DCHECK(!scheduled_commit_.get()) << "Deleting without cleanup"; |
| 220 STLDeleteContainerPointers(queued_history_db_tasks_.begin(), |
| 221 queued_history_db_tasks_.end()); |
215 queued_history_db_tasks_.clear(); | 222 queued_history_db_tasks_.clear(); |
216 | 223 |
217 #if defined(OS_ANDROID) | 224 #if defined(OS_ANDROID) |
218 // Release AndroidProviderBackend before other objects. | 225 // Release AndroidProviderBackend before other objects. |
219 android_provider_backend_.reset(); | 226 android_provider_backend_.reset(); |
220 #endif | 227 #endif |
221 | 228 |
222 // First close the databases before optionally running the "destroy" task. | 229 // First close the databases before optionally running the "destroy" task. |
223 CloseAllDatabases(); | 230 CloseAllDatabases(); |
224 | 231 |
(...skipping 2098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2323 void HistoryBackend::CancelScheduledCommit() { | 2330 void HistoryBackend::CancelScheduledCommit() { |
2324 if (scheduled_commit_.get()) { | 2331 if (scheduled_commit_.get()) { |
2325 scheduled_commit_->Cancel(); | 2332 scheduled_commit_->Cancel(); |
2326 scheduled_commit_ = NULL; | 2333 scheduled_commit_ = NULL; |
2327 } | 2334 } |
2328 } | 2335 } |
2329 | 2336 |
2330 void HistoryBackend::ProcessDBTaskImpl() { | 2337 void HistoryBackend::ProcessDBTaskImpl() { |
2331 if (!db_) { | 2338 if (!db_) { |
2332 // db went away, release all the refs. | 2339 // db went away, release all the refs. |
| 2340 STLDeleteContainerPointers(queued_history_db_tasks_.begin(), |
| 2341 queued_history_db_tasks_.end()); |
2333 queued_history_db_tasks_.clear(); | 2342 queued_history_db_tasks_.clear(); |
2334 return; | 2343 return; |
2335 } | 2344 } |
2336 | 2345 |
2337 // Remove any canceled tasks. | 2346 // Remove any canceled tasks. |
2338 while (!queued_history_db_tasks_.empty()) { | 2347 while (!queued_history_db_tasks_.empty()) { |
2339 QueuedHistoryDBTask& task = queued_history_db_tasks_.front(); | 2348 QueuedHistoryDBTask* task = queued_history_db_tasks_.front(); |
2340 if (!task.is_canceled()) { | 2349 if (!task->is_canceled()) |
2341 break; | 2350 break; |
2342 } | 2351 |
| 2352 delete task; |
2343 queued_history_db_tasks_.pop_front(); | 2353 queued_history_db_tasks_.pop_front(); |
2344 } | 2354 } |
2345 if (queued_history_db_tasks_.empty()) | 2355 if (queued_history_db_tasks_.empty()) |
2346 return; | 2356 return; |
2347 | 2357 |
2348 // Run the first task. | 2358 // Run the first task. |
2349 QueuedHistoryDBTask task = queued_history_db_tasks_.front(); | 2359 scoped_ptr<QueuedHistoryDBTask> task(queued_history_db_tasks_.front()); |
2350 queued_history_db_tasks_.pop_front(); | 2360 queued_history_db_tasks_.pop_front(); |
2351 if (task.RunOnDBThread(this, db_.get())) { | 2361 if (task->Run(this, db_.get())) { |
2352 // The task is done, notify the callback. | 2362 // The task is done, notify the callback. |
2353 task.DoneRunOnMainThread(); | 2363 task->DoneRun(); |
2354 } else { | 2364 } else { |
2355 // The task wants to run some more. Schedule it at the end of the current | 2365 // The task wants to run some more. Schedule it at the end of the current |
2356 // tasks, and process it after an invoke later. | 2366 // tasks, and process it after an invoke later. |
2357 queued_history_db_tasks_.insert(queued_history_db_tasks_.end(), task); | 2367 queued_history_db_tasks_.push_back(task.release()); |
2358 base::MessageLoop::current()->PostTask( | 2368 base::MessageLoop::current()->PostTask( |
2359 FROM_HERE, base::Bind(&HistoryBackend::ProcessDBTaskImpl, this)); | 2369 FROM_HERE, base::Bind(&HistoryBackend::ProcessDBTaskImpl, this)); |
2360 } | 2370 } |
2361 } | 2371 } |
2362 | 2372 |
2363 //////////////////////////////////////////////////////////////////////////////// | 2373 //////////////////////////////////////////////////////////////////////////////// |
2364 // | 2374 // |
2365 // Generic operations | 2375 // Generic operations |
2366 // | 2376 // |
2367 //////////////////////////////////////////////////////////////////////////////// | 2377 //////////////////////////////////////////////////////////////////////////////// |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2533 // The expirer keeps tabs on the active databases. Tell it about the | 2543 // The expirer keeps tabs on the active databases. Tell it about the |
2534 // databases which will be closed. | 2544 // databases which will be closed. |
2535 expirer_.SetDatabases(NULL, NULL); | 2545 expirer_.SetDatabases(NULL, NULL); |
2536 | 2546 |
2537 // Reopen a new transaction for |db_| for the sake of CloseAllDatabases(). | 2547 // Reopen a new transaction for |db_| for the sake of CloseAllDatabases(). |
2538 db_->BeginTransaction(); | 2548 db_->BeginTransaction(); |
2539 CloseAllDatabases(); | 2549 CloseAllDatabases(); |
2540 } | 2550 } |
2541 | 2551 |
2542 void HistoryBackend::ProcessDBTask( | 2552 void HistoryBackend::ProcessDBTask( |
2543 scoped_refptr<HistoryDBTask> task, | 2553 scoped_ptr<HistoryDBTask> task, |
2544 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, | 2554 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, |
2545 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { | 2555 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { |
2546 bool scheduled = !queued_history_db_tasks_.empty(); | 2556 bool scheduled = !queued_history_db_tasks_.empty(); |
2547 queued_history_db_tasks_.insert( | 2557 queued_history_db_tasks_.push_back( |
2548 queued_history_db_tasks_.end(), | 2558 new QueuedHistoryDBTask(task.Pass(), origin_loop, is_canceled)); |
2549 QueuedHistoryDBTask(task, origin_loop, is_canceled)); | |
2550 if (!scheduled) | 2559 if (!scheduled) |
2551 ProcessDBTaskImpl(); | 2560 ProcessDBTaskImpl(); |
2552 } | 2561 } |
2553 | 2562 |
2554 void HistoryBackend::BroadcastNotifications( | 2563 void HistoryBackend::BroadcastNotifications( |
2555 int type, | 2564 int type, |
2556 scoped_ptr<HistoryDetails> details) { | 2565 scoped_ptr<HistoryDetails> details) { |
2557 // |delegate_| may be NULL if |this| is in the process of closing (closed by | 2566 // |delegate_| may be NULL if |this| is in the process of closing (closed by |
2558 // HistoryService -> HistoryBackend::Closing(). | 2567 // HistoryService -> HistoryBackend::Closing(). |
2559 if (delegate_) | 2568 if (delegate_) |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2744 int rank = kPageVisitStatsMaxTopSites; | 2753 int rank = kPageVisitStatsMaxTopSites; |
2745 std::map<GURL, int>::const_iterator it = most_visited_urls_map_.find(url); | 2754 std::map<GURL, int>::const_iterator it = most_visited_urls_map_.find(url); |
2746 if (it != most_visited_urls_map_.end()) | 2755 if (it != most_visited_urls_map_.end()) |
2747 rank = (*it).second; | 2756 rank = (*it).second; |
2748 UMA_HISTOGRAM_ENUMERATION("History.TopSitesVisitsByRank", | 2757 UMA_HISTOGRAM_ENUMERATION("History.TopSitesVisitsByRank", |
2749 rank, kPageVisitStatsMaxTopSites + 1); | 2758 rank, kPageVisitStatsMaxTopSites + 1); |
2750 } | 2759 } |
2751 #endif | 2760 #endif |
2752 | 2761 |
2753 } // namespace history | 2762 } // namespace history |
OLD | NEW |