| 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 | |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |