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