OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/sync/model_impl/model_type_store_impl.h" | 5 #include "components/sync/model_impl/model_type_store_impl.h" |
6 | 6 |
| 7 #include <map> |
7 #include <utility> | 8 #include <utility> |
8 | 9 |
9 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/lazy_instance.h" |
10 #include "base/location.h" | 12 #include "base/location.h" |
11 #include "base/logging.h" | 13 #include "base/logging.h" |
12 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
13 #include "base/optional.h" | 15 #include "base/optional.h" |
14 #include "base/task_runner_util.h" | 16 #include "base/task_runner_util.h" |
| 17 #include "base/task_scheduler/post_task.h" |
| 18 #include "base/task_scheduler/task_traits.h" |
15 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
16 #include "components/sync/model/model_error.h" | 20 #include "components/sync/model/model_error.h" |
17 #include "components/sync/model_impl/model_type_store_backend.h" | 21 #include "components/sync/model_impl/model_type_store_backend.h" |
18 #include "components/sync/protocol/entity_metadata.pb.h" | 22 #include "components/sync/protocol/entity_metadata.pb.h" |
19 #include "components/sync/protocol/model_type_state.pb.h" | 23 #include "components/sync/protocol/model_type_state.pb.h" |
20 #include "third_party/leveldatabase/src/include/leveldb/env.h" | 24 #include "third_party/leveldatabase/src/include/leveldb/env.h" |
21 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" | 25 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
22 | 26 |
23 namespace syncer { | 27 namespace syncer { |
24 | 28 |
(...skipping 18 matching lines...) Expand all Loading... |
43 // Formats key prefix for metadata records of |type|. | 47 // Formats key prefix for metadata records of |type|. |
44 std::string FormatMetaPrefix(ModelType type) { | 48 std::string FormatMetaPrefix(ModelType type) { |
45 return std::string(GetModelTypeRootTag(type)) + kMetadataPrefix; | 49 return std::string(GetModelTypeRootTag(type)) + kMetadataPrefix; |
46 } | 50 } |
47 | 51 |
48 // Formats key for global metadata record of |type|. | 52 // Formats key for global metadata record of |type|. |
49 std::string FormatGlobalMetadataKey(ModelType type) { | 53 std::string FormatGlobalMetadataKey(ModelType type) { |
50 return std::string(GetModelTypeRootTag(type)) + kGlobalMetadataKey; | 54 return std::string(GetModelTypeRootTag(type)) + kGlobalMetadataKey; |
51 } | 55 } |
52 | 56 |
| 57 // Holds a one to one mapping between profile path and SequencedTaskRunner. This |
| 58 // class is expected to be accessed on any thread, and uses a lock to guarantee |
| 59 // thread safety. The task runners are held onto by scoped_refptrs, and since |
| 60 // this class is leaky, none of these task runners are ever destroyed. |
| 61 class TaskRunnerMap { |
| 62 public: |
| 63 TaskRunnerMap() = default; |
| 64 |
| 65 scoped_refptr<base::SequencedTaskRunner> GetOrCreateTaskRunner( |
| 66 const std::string& path) { |
| 67 base::AutoLock scoped_lock(lock_); |
| 68 auto iter = task_runner_map_.find(path); |
| 69 if (iter == task_runner_map_.end()) { |
| 70 scoped_refptr<base::SequencedTaskRunner> task_runner = |
| 71 CreateSequencedTaskRunnerWithTraits( |
| 72 base::TaskTraits().MayBlock().WithShutdownBehavior( |
| 73 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
| 74 task_runner_map_[path] = task_runner; |
| 75 return task_runner; |
| 76 } else { |
| 77 return iter->second; |
| 78 } |
| 79 } |
| 80 |
| 81 private: |
| 82 mutable base::Lock lock_; |
| 83 std::map<std::string, scoped_refptr<base::SequencedTaskRunner>> |
| 84 task_runner_map_; |
| 85 |
| 86 DISALLOW_COPY_AND_ASSIGN(TaskRunnerMap); |
| 87 }; |
| 88 |
| 89 base::LazyInstance<TaskRunnerMap>::Leaky task_runner_map_singleton_ = |
| 90 LAZY_INSTANCE_INITIALIZER; |
| 91 |
53 } // namespace | 92 } // namespace |
54 | 93 |
55 // static | 94 // static |
56 leveldb::WriteBatch* ModelTypeStoreImpl::GetLeveldbWriteBatch( | 95 leveldb::WriteBatch* ModelTypeStoreImpl::GetLeveldbWriteBatch( |
57 WriteBatch* write_batch) { | 96 WriteBatch* write_batch) { |
58 return static_cast<WriteBatchImpl*>(write_batch)->leveldb_write_batch_.get(); | 97 return static_cast<WriteBatchImpl*>(write_batch)->leveldb_write_batch_.get(); |
59 } | 98 } |
60 | 99 |
61 std::string ModelTypeStoreImpl::FormatDataKey(const std::string& id) { | 100 std::string ModelTypeStoreImpl::FormatDataKey(const std::string& id) { |
62 return data_prefix_ + id; | 101 return data_prefix_ + id; |
(...skipping 20 matching lines...) Expand all Loading... |
83 ModelTypeStoreImpl::~ModelTypeStoreImpl() { | 122 ModelTypeStoreImpl::~ModelTypeStoreImpl() { |
84 DCHECK(CalledOnValidThread()); | 123 DCHECK(CalledOnValidThread()); |
85 backend_task_runner_->PostTask( | 124 backend_task_runner_->PostTask( |
86 FROM_HERE, base::Bind(&NoOpForBackendDtor, base::Passed(&backend_))); | 125 FROM_HERE, base::Bind(&NoOpForBackendDtor, base::Passed(&backend_))); |
87 } | 126 } |
88 | 127 |
89 // static | 128 // static |
90 void ModelTypeStoreImpl::CreateStore( | 129 void ModelTypeStoreImpl::CreateStore( |
91 ModelType type, | 130 ModelType type, |
92 const std::string& path, | 131 const std::string& path, |
93 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, | |
94 const InitCallback& callback) { | 132 const InitCallback& callback) { |
95 DCHECK(!callback.is_null()); | 133 DCHECK(!callback.is_null()); |
96 std::unique_ptr<leveldb::Env> env; | 134 std::unique_ptr<leveldb::Env> env; |
| 135 scoped_refptr<base::SequencedTaskRunner> task_runner = |
| 136 task_runner_map_singleton_.Get().GetOrCreateTaskRunner(path); |
97 std::unique_ptr<Result> result(new Result()); | 137 std::unique_ptr<Result> result(new Result()); |
98 auto task = base::Bind(&ModelTypeStoreBackend::GetOrCreateBackend, path, | 138 auto task = base::Bind(&ModelTypeStoreBackend::GetOrCreateBackend, path, |
99 base::Passed(&env), result.get()); | 139 base::Passed(&env), result.get()); |
100 auto reply = | 140 auto reply = base::Bind(&ModelTypeStoreImpl::BackendInitDone, type, |
101 base::Bind(&ModelTypeStoreImpl::BackendInitDone, type, | 141 base::Passed(&result), task_runner, callback); |
102 base::Passed(&result), blocking_task_runner, callback); | 142 base::PostTaskAndReplyWithResult(task_runner.get(), FROM_HERE, task, reply); |
103 | |
104 base::PostTaskAndReplyWithResult(blocking_task_runner.get(), FROM_HERE, task, | |
105 reply); | |
106 } | 143 } |
107 | 144 |
108 // static | 145 // static |
109 void ModelTypeStoreImpl::CreateInMemoryStoreForTest( | 146 void ModelTypeStoreImpl::CreateInMemoryStoreForTest( |
110 ModelType type, | 147 ModelType type, |
111 const InitCallback& callback) { | 148 const InitCallback& callback) { |
112 DCHECK(!callback.is_null()); | 149 DCHECK(!callback.is_null()); |
113 | 150 |
114 std::unique_ptr<leveldb::Env> env = | 151 std::unique_ptr<leveldb::Env> env = |
115 ModelTypeStoreBackend::CreateInMemoryEnv(); | 152 ModelTypeStoreBackend::CreateInMemoryEnv(); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 } | 415 } |
379 | 416 |
380 ModelTypeStoreImpl::WriteBatchImpl::WriteBatchImpl(ModelTypeStore* store) | 417 ModelTypeStoreImpl::WriteBatchImpl::WriteBatchImpl(ModelTypeStore* store) |
381 : WriteBatch(store) { | 418 : WriteBatch(store) { |
382 leveldb_write_batch_ = base::MakeUnique<leveldb::WriteBatch>(); | 419 leveldb_write_batch_ = base::MakeUnique<leveldb::WriteBatch>(); |
383 } | 420 } |
384 | 421 |
385 ModelTypeStoreImpl::WriteBatchImpl::~WriteBatchImpl() {} | 422 ModelTypeStoreImpl::WriteBatchImpl::~WriteBatchImpl() {} |
386 | 423 |
387 } // namespace syncer | 424 } // namespace syncer |
OLD | NEW |