| Index: components/sync/model_impl/model_type_store_impl.cc
|
| diff --git a/components/sync/model_impl/model_type_store_impl.cc b/components/sync/model_impl/model_type_store_impl.cc
|
| index e4d7fcf5a4e68182f255dae21f59bf371f80488e..2e940061666ad6a421a6a91693c61d6fcca00229 100644
|
| --- a/components/sync/model_impl/model_type_store_impl.cc
|
| +++ b/components/sync/model_impl/model_type_store_impl.cc
|
| @@ -4,14 +4,18 @@
|
|
|
| #include "components/sync/model_impl/model_type_store_impl.h"
|
|
|
| +#include <map>
|
| #include <utility>
|
|
|
| #include "base/bind.h"
|
| +#include "base/lazy_instance.h"
|
| #include "base/location.h"
|
| #include "base/logging.h"
|
| #include "base/memory/ptr_util.h"
|
| #include "base/optional.h"
|
| #include "base/task_runner_util.h"
|
| +#include "base/task_scheduler/post_task.h"
|
| +#include "base/task_scheduler/task_traits.h"
|
| #include "base/threading/thread_task_runner_handle.h"
|
| #include "components/sync/model/model_error.h"
|
| #include "components/sync/model_impl/model_type_store_backend.h"
|
| @@ -50,6 +54,41 @@ std::string FormatGlobalMetadataKey(ModelType type) {
|
| return std::string(GetModelTypeRootTag(type)) + kGlobalMetadataKey;
|
| }
|
|
|
| +// Holds a one to one mapping between profile path and SequencedTaskRunner. This
|
| +// class is expected to be accessed on any thread, and uses a lock to guarantee
|
| +// thread safety. The task runners are held onto by scoped_refptrs, and since
|
| +// this class is leaky, none of these task runners are ever destroyed.
|
| +class TaskRunnerMap {
|
| + public:
|
| + TaskRunnerMap() = default;
|
| +
|
| + scoped_refptr<base::SequencedTaskRunner> GetOrCreateTaskRunner(
|
| + const std::string& path) {
|
| + base::AutoLock scoped_lock(lock_);
|
| + auto iter = task_runner_map_.find(path);
|
| + if (iter == task_runner_map_.end()) {
|
| + scoped_refptr<base::SequencedTaskRunner> task_runner =
|
| + CreateSequencedTaskRunnerWithTraits(
|
| + base::TaskTraits().MayBlock().WithShutdownBehavior(
|
| + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN));
|
| + task_runner_map_[path] = task_runner;
|
| + return task_runner;
|
| + } else {
|
| + return iter->second;
|
| + }
|
| + }
|
| +
|
| + private:
|
| + mutable base::Lock lock_;
|
| + std::map<std::string, scoped_refptr<base::SequencedTaskRunner>>
|
| + task_runner_map_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TaskRunnerMap);
|
| +};
|
| +
|
| +base::LazyInstance<TaskRunnerMap>::Leaky task_runner_map_singleton_ =
|
| + LAZY_INSTANCE_INITIALIZER;
|
| +
|
| } // namespace
|
|
|
| // static
|
| @@ -90,19 +129,17 @@ ModelTypeStoreImpl::~ModelTypeStoreImpl() {
|
| void ModelTypeStoreImpl::CreateStore(
|
| ModelType type,
|
| const std::string& path,
|
| - scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
|
| const InitCallback& callback) {
|
| DCHECK(!callback.is_null());
|
| std::unique_ptr<leveldb::Env> env;
|
| + scoped_refptr<base::SequencedTaskRunner> task_runner =
|
| + task_runner_map_singleton_.Get().GetOrCreateTaskRunner(path);
|
| std::unique_ptr<Result> result(new Result());
|
| auto task = base::Bind(&ModelTypeStoreBackend::GetOrCreateBackend, path,
|
| base::Passed(&env), result.get());
|
| - auto reply =
|
| - base::Bind(&ModelTypeStoreImpl::BackendInitDone, type,
|
| - base::Passed(&result), blocking_task_runner, callback);
|
| -
|
| - base::PostTaskAndReplyWithResult(blocking_task_runner.get(), FROM_HERE, task,
|
| - reply);
|
| + auto reply = base::Bind(&ModelTypeStoreImpl::BackendInitDone, type,
|
| + base::Passed(&result), task_runner, callback);
|
| + base::PostTaskAndReplyWithResult(task_runner.get(), FROM_HERE, task, reply);
|
| }
|
|
|
| // static
|
|
|