| 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 "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 Loading... |
| 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 |
| 117 QueuedHistoryDBTask::QueuedHistoryDBTask( | 155 QueuedHistoryDBTask::QueuedHistoryDBTask( |
| 118 std::unique_ptr<HistoryDBTask> task, | 156 std::unique_ptr<HistoryDBTask> task, |
| 119 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, | 157 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, |
| 120 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) | 158 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) |
| 121 : task_(std::move(task)), | 159 : task_(std::move(task)), |
| 122 origin_loop_(origin_loop), | 160 origin_loop_(origin_loop), |
| 123 is_canceled_(is_canceled) { | 161 is_canceled_(is_canceled) { |
| 124 DCHECK(task_); | 162 DCHECK(task_); |
| 125 DCHECK(origin_loop_); | 163 DCHECK(origin_loop_); |
| 126 DCHECK(!is_canceled_.is_null()); | 164 DCHECK(!is_canceled_.is_null()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 scoped_refptr<base::SequencedTaskRunner> task_runner) | 210 scoped_refptr<base::SequencedTaskRunner> task_runner) |
| 173 : delegate_(delegate), | 211 : delegate_(delegate), |
| 174 scheduled_kill_db_(false), | 212 scheduled_kill_db_(false), |
| 175 expirer_(this, backend_client.get(), task_runner), | 213 expirer_(this, backend_client.get(), task_runner), |
| 176 recent_redirects_(kMaxRedirectCount), | 214 recent_redirects_(kMaxRedirectCount), |
| 177 segment_queried_(false), | 215 segment_queried_(false), |
| 178 backend_client_(std::move(backend_client)), | 216 backend_client_(std::move(backend_client)), |
| 179 task_runner_(task_runner) {} | 217 task_runner_(task_runner) {} |
| 180 | 218 |
| 181 HistoryBackend::~HistoryBackend() { | 219 HistoryBackend::~HistoryBackend() { |
| 182 DCHECK(scheduled_commit_.IsCancelled()) << "Deleting without cleanup"; | 220 DCHECK(!scheduled_commit_) << "Deleting without cleanup"; |
| 183 queued_history_db_tasks_.clear(); | 221 queued_history_db_tasks_.clear(); |
| 184 | 222 |
| 185 // Release stashed embedder object before cleaning up the databases. | 223 // Release stashed embedder object before cleaning up the databases. |
| 186 supports_user_data_helper_.reset(); | 224 supports_user_data_helper_.reset(); |
| 187 | 225 |
| 188 // First close the databases before optionally running the "destroy" task. | 226 // First close the databases before optionally running the "destroy" task. |
| 189 CloseAllDatabases(); | 227 CloseAllDatabases(); |
| 190 | 228 |
| 191 if (!backend_destroy_task_.is_null()) { | 229 if (!backend_destroy_task_.is_null()) { |
| 192 // Notify an interested party (typically a unit test) that we're done. | 230 // Notify an interested party (typically a unit test) that we're done. |
| (...skipping 2004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2197 | 2235 |
| 2198 if (thumbnail_db_) { | 2236 if (thumbnail_db_) { |
| 2199 thumbnail_db_->CommitTransaction(); | 2237 thumbnail_db_->CommitTransaction(); |
| 2200 DCHECK_EQ(thumbnail_db_->transaction_nesting(), 0) | 2238 DCHECK_EQ(thumbnail_db_->transaction_nesting(), 0) |
| 2201 << "Somebody left a transaction open"; | 2239 << "Somebody left a transaction open"; |
| 2202 thumbnail_db_->BeginTransaction(); | 2240 thumbnail_db_->BeginTransaction(); |
| 2203 } | 2241 } |
| 2204 } | 2242 } |
| 2205 | 2243 |
| 2206 void HistoryBackend::ScheduleCommit() { | 2244 void HistoryBackend::ScheduleCommit() { |
| 2207 // Non-cancelled means there's an already scheduled commit. Note that | 2245 if (scheduled_commit_) |
| 2208 // CancelableClosure starts cancelled with the default constructor. | |
| 2209 if (!scheduled_commit_.IsCancelled()) | |
| 2210 return; | 2246 return; |
| 2211 | 2247 scheduled_commit_ = new CommitLaterTask(this); |
| 2212 scheduled_commit_.Reset( | |
| 2213 base::Bind(&HistoryBackend::Commit, base::Unretained(this))); | |
| 2214 | |
| 2215 task_runner_->PostDelayedTask( | 2248 task_runner_->PostDelayedTask( |
| 2216 FROM_HERE, scheduled_commit_.callback(), | 2249 FROM_HERE, |
| 2250 base::Bind(&CommitLaterTask::RunCommit, scheduled_commit_), |
| 2217 base::TimeDelta::FromSeconds(kCommitIntervalSeconds)); | 2251 base::TimeDelta::FromSeconds(kCommitIntervalSeconds)); |
| 2218 } | 2252 } |
| 2219 | 2253 |
| 2220 void HistoryBackend::CancelScheduledCommit() { | 2254 void HistoryBackend::CancelScheduledCommit() { |
| 2221 scheduled_commit_.Cancel(); | 2255 if (scheduled_commit_) { |
| 2256 scheduled_commit_->Cancel(); |
| 2257 scheduled_commit_ = nullptr; |
| 2258 } |
| 2222 } | 2259 } |
| 2223 | 2260 |
| 2224 void HistoryBackend::ProcessDBTaskImpl() { | 2261 void HistoryBackend::ProcessDBTaskImpl() { |
| 2225 if (!db_) { | 2262 if (!db_) { |
| 2226 // db went away, release all the refs. | 2263 // db went away, release all the refs. |
| 2227 queued_history_db_tasks_.clear(); | 2264 queued_history_db_tasks_.clear(); |
| 2228 return; | 2265 return; |
| 2229 } | 2266 } |
| 2230 | 2267 |
| 2231 // Remove any canceled tasks. | 2268 // Remove any canceled tasks. |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2609 // transaction is currently open. | 2646 // transaction is currently open. |
| 2610 db_->CommitTransaction(); | 2647 db_->CommitTransaction(); |
| 2611 db_->Vacuum(); | 2648 db_->Vacuum(); |
| 2612 db_->BeginTransaction(); | 2649 db_->BeginTransaction(); |
| 2613 db_->GetStartDate(&first_recorded_time_); | 2650 db_->GetStartDate(&first_recorded_time_); |
| 2614 | 2651 |
| 2615 return true; | 2652 return true; |
| 2616 } | 2653 } |
| 2617 | 2654 |
| 2618 } // namespace history | 2655 } // namespace history |
| OLD | NEW |