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

Unified Diff: components/history/core/browser/history_backend.cc

Issue 2697513002: Revert of Refactor History's CommitLaterTask with CancelableCallback (Closed)
Patch Set: Created 3 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: components/history/core/browser/history_backend.cc
diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc
index f3a489a3343522a535eedb5608098f2704b69985..08cacf54212abaa3b3639e655f75878563e0b986 100644
--- a/components/history/core/browser/history_backend.cc
+++ b/components/history/core/browser/history_backend.cc
@@ -114,6 +114,44 @@
return mv;
}
+// This task is run on a timer so that commits happen at regular intervals
+// so they are batched together. The important thing about this class is that
+// it supports canceling of the task so the reference to the backend will be
+// freed. The problem is that when history is shutting down, there is likely
+// to be one of these commits still pending and holding a reference.
+//
+// The backend can call Cancel to have this task release the reference. The
+// task will still run (if we ever get to processing the event before
+// shutdown), but it will not do anything.
+//
+// Note that this is a refcounted object and is not a task in itself. It should
+// be assigned to a RunnableMethod.
+//
+// TODO(brettw): bug 1165182: This should be replaced with a
+// base::WeakPtrFactory which will handle everything automatically (like we do
+// in ExpireHistoryBackend).
+class CommitLaterTask : public base::RefCounted<CommitLaterTask> {
+ public:
+ explicit CommitLaterTask(HistoryBackend* history_backend)
+ : history_backend_(history_backend) {}
+
+ // The backend will call this function if it is being destroyed so that we
+ // release our reference.
+ void Cancel() { history_backend_ = nullptr; }
+
+ void RunCommit() {
+ if (history_backend_)
+ history_backend_->Commit();
+ }
+
+ private:
+ friend class base::RefCounted<CommitLaterTask>;
+
+ ~CommitLaterTask() {}
+
+ scoped_refptr<HistoryBackend> history_backend_;
+};
+
QueuedHistoryDBTask::QueuedHistoryDBTask(
std::unique_ptr<HistoryDBTask> task,
scoped_refptr<base::SingleThreadTaskRunner> origin_loop,
@@ -179,7 +217,7 @@
task_runner_(task_runner) {}
HistoryBackend::~HistoryBackend() {
- DCHECK(scheduled_commit_.IsCancelled()) << "Deleting without cleanup";
+ DCHECK(!scheduled_commit_) << "Deleting without cleanup";
queued_history_db_tasks_.clear();
// Release stashed embedder object before cleaning up the databases.
@@ -2204,21 +2242,20 @@
}
void HistoryBackend::ScheduleCommit() {
- // Non-cancelled means there's an already scheduled commit. Note that
- // CancelableClosure starts cancelled with the default constructor.
- if (!scheduled_commit_.IsCancelled())
- return;
-
- scheduled_commit_.Reset(
- base::Bind(&HistoryBackend::Commit, base::Unretained(this)));
-
+ if (scheduled_commit_)
+ return;
+ scheduled_commit_ = new CommitLaterTask(this);
task_runner_->PostDelayedTask(
- FROM_HERE, scheduled_commit_.callback(),
+ FROM_HERE,
+ base::Bind(&CommitLaterTask::RunCommit, scheduled_commit_),
base::TimeDelta::FromSeconds(kCommitIntervalSeconds));
}
void HistoryBackend::CancelScheduledCommit() {
- scheduled_commit_.Cancel();
+ if (scheduled_commit_) {
+ scheduled_commit_->Cancel();
+ scheduled_commit_ = nullptr;
+ }
}
void HistoryBackend::ProcessDBTaskImpl() {

Powered by Google App Engine
This is Rietveld 408576698