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,