Fix/prevent race condition on profile re-loading
This CL switches to using `CreateTaskRunnerForResource()` when the BTM
service is using a persistent/on-disk database, avoiding a scenario
where a new (different) task runner is used to open the BTM db while the
original task runner is in the process of closing it.
`CreateTaskRunnerForResource()` prevents this by only creating a new
task runner if there isn't already one associated with the db file. If
there is already a task runner associated with the db file, it returns a
reference to that one.
Reusing the same task runner means the task to open the db won't start
until the task to close it has completed.
Bug: 369635654
Change-Id: I780ceced23d01c3e1441f0ad8c1802ade4a59c0e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6386752
Reviewed-by: Ryan Tarpine <rtarpine@chromium.org>
Commit-Queue: Joshua Hood <jdh@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1437050}
diff --git a/content/browser/btm/btm_service_impl.cc b/content/browser/btm/btm_service_impl.cc
index 2cad78c..1c1daeb 100644
--- a/content/browser/btm/btm_service_impl.cc
+++ b/content/browser/btm/btm_service_impl.cc
@@ -322,7 +322,14 @@
}
}
- storage_ = base::SequenceBound<BtmStorage>(CreateTaskRunner(), path_to_use);
+ if (path_to_use.has_value()) {
+ // If opening a persisted database, use `CreateTaskRunnerForResource()` to
+ // avoid race condition during profile re-loading.
+ storage_ = base::SequenceBound<BtmStorage>(
+ CreateTaskRunnerForResource(path_to_use.value()), path_to_use);
+ } else {
+ storage_ = base::SequenceBound<BtmStorage>(CreateTaskRunner(), path_to_use);
+ }
repeating_timer_ = CreateTimer();
repeating_timer_->Start();
@@ -365,6 +372,18 @@
base::ThreadPolicy::PREFER_BACKGROUND});
}
+scoped_refptr<base::SequencedTaskRunner>
+BtmServiceImpl::CreateTaskRunnerForResource(const base::FilePath& path) {
+ if (base::FeatureList::IsEnabled(kDipsOnForegroundSequence)) {
+ return base::ThreadPool::CreateSequencedTaskRunnerForResource(
+ {base::MayBlock()}, path);
+ }
+ return base::ThreadPool::CreateSequencedTaskRunnerForResource(
+ {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+ base::ThreadPolicy::PREFER_BACKGROUND},
+ path);
+}
+
BtmCookieMode BtmServiceImpl::GetCookieMode() const {
return GetBtmCookieMode(browser_context_->IsOffTheRecord());
}
diff --git a/content/browser/btm/btm_service_impl.h b/content/browser/btm/btm_service_impl.h
index 5563bb9..f6c629a 100644
--- a/content/browser/btm/btm_service_impl.h
+++ b/content/browser/btm/btm_service_impl.h
@@ -147,6 +147,8 @@
base::RepeatingCallback<void(const GURL&)> stateful_bounce_callback);
scoped_refptr<base::SequencedTaskRunner> CreateTaskRunner();
+ scoped_refptr<base::SequencedTaskRunner> CreateTaskRunnerForResource(
+ const base::FilePath& path);
void OnTimerFired();
void DeleteBtmEligibleState(DeletedSitesCallback callback,