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

Unified Diff: components/sync/model_impl/model_type_store_backend.cc

Issue 2732333003: [Sync] ModelTypeStore factory shouldn't require valid PSS to function correctly (Closed)
Patch Set: Address comments Created 3 years, 9 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/sync/model_impl/model_type_store_backend.cc
diff --git a/components/sync/model_impl/model_type_store_backend.cc b/components/sync/model_impl/model_type_store_backend.cc
index afc6fe8f3d7c7f0c37eb2e3ff2ce29b38625a2f9..a277b82f8cc0918bceae1263691540fafa80bded 100644
--- a/components/sync/model_impl/model_type_store_backend.cc
+++ b/components/sync/model_impl/model_type_store_backend.cc
@@ -7,8 +7,10 @@
#include <utility>
#include "base/files/file_path.h"
+#include "base/lazy_instance.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
+#include "base/synchronization/lock.h"
#include "components/sync/protocol/model_type_store_schema_descriptor.pb.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
@@ -31,10 +33,6 @@ const char ModelTypeStoreBackend::kDBSchemaDescriptorRecordId[] =
const char ModelTypeStoreBackend::kStoreInitResultHistogramName[] =
"Sync.ModelTypeStoreInitResult";
-// static
-base::LazyInstance<ModelTypeStoreBackend::BackendMap>::DestructorAtExit
- ModelTypeStoreBackend::backend_map_ = LAZY_INSTANCE_INITIALIZER;
-
namespace {
StoreInitResultForHistogram LevelDbStatusToStoreInitResult(
@@ -54,13 +52,59 @@ StoreInitResultForHistogram LevelDbStatusToStoreInitResult(
return STORE_INIT_RESULT_UNKNOWN;
}
+// BackendMap tracks created ModelTypeStoreBackends ensuring at most one backend
+// exists for a given path. BackendMap keeps non-owning pointer to backend
+// allowing backend lifetime to be controlled by consumers. Since backends can
+// run concurrently on different threads all map operations are guarded by lock.
+class BackendMap {
+ public:
+ BackendMap() = default;
+
+ // Returns backend reference or nullptr if backend for |path| is not in the
+ // map.
+ scoped_refptr<ModelTypeStoreBackend> GetBackend(
+ const std::string& path) const;
+ // Adds backend into the map ensuring it wasn't added before.
+ void SetBackend(const std::string& path, ModelTypeStoreBackend* backend);
+ void EraseBackend(const std::string& path);
+
+ private:
+ mutable base::Lock lock_;
+
+ std::unordered_map<std::string, ModelTypeStoreBackend*> backends_;
+
+ DISALLOW_COPY_AND_ASSIGN(BackendMap);
+};
+
+base::LazyInstance<BackendMap>::DestructorAtExit backend_map =
+ LAZY_INSTANCE_INITIALIZER;
+
+scoped_refptr<ModelTypeStoreBackend> BackendMap::GetBackend(
+ const std::string& path) const {
+ base::AutoLock scoped_lock(lock_);
+ auto it = backends_.find(path);
+ return (it == backends_.end()) ? nullptr : it->second;
+}
+
+void BackendMap::SetBackend(const std::string& path,
+ ModelTypeStoreBackend* backend) {
+ base::AutoLock scoped_lock(lock_);
+ DCHECK(backends_.find(path) == backends_.end());
+ backends_[path] = backend;
+}
+
+void BackendMap::EraseBackend(const std::string& path) {
+ base::AutoLock scoped_lock(lock_);
+ backends_.erase(path);
+}
+
} // namespace
ModelTypeStoreBackend::ModelTypeStoreBackend(const std::string& path)
: path_(path) {}
ModelTypeStoreBackend::~ModelTypeStoreBackend() {
- backend_map_.Get().erase(path_);
+ backend_map.Get().EraseBackend(path_);
}
std::unique_ptr<leveldb::Env> ModelTypeStoreBackend::CreateInMemoryEnv() {
@@ -72,18 +116,19 @@ scoped_refptr<ModelTypeStoreBackend> ModelTypeStoreBackend::GetOrCreateBackend(
const std::string& path,
std::unique_ptr<leveldb::Env> env,
ModelTypeStore::Result* result) {
- if (backend_map_.Get().find(path) != backend_map_.Get().end()) {
+ scoped_refptr<ModelTypeStoreBackend> backend =
+ backend_map.Get().GetBackend(path);
+ if (backend) {
*result = ModelTypeStore::Result::SUCCESS;
- return make_scoped_refptr(backend_map_.Get()[path]);
+ return backend;
}
- scoped_refptr<ModelTypeStoreBackend> backend =
- new ModelTypeStoreBackend(path);
+ backend = new ModelTypeStoreBackend(path);
*result = backend->Init(path, std::move(env));
if (*result == ModelTypeStore::Result::SUCCESS) {
- backend_map_.Get()[path] = backend.get();
+ backend_map.Get().SetBackend(path, backend.get());
} else {
backend = nullptr;
}
@@ -94,7 +139,7 @@ scoped_refptr<ModelTypeStoreBackend> ModelTypeStoreBackend::GetOrCreateBackend(
ModelTypeStore::Result ModelTypeStoreBackend::Init(
const std::string& path,
std::unique_ptr<leveldb::Env> env) {
- DFAKE_SCOPED_LOCK(push_pop_);
+ DCHECK(sequence_checker_.CalledOnValidSequence());
env_ = std::move(env);
@@ -162,7 +207,7 @@ ModelTypeStore::Result ModelTypeStoreBackend::ReadRecordsWithPrefix(
const ModelTypeStore::IdList& id_list,
ModelTypeStore::RecordList* record_list,
ModelTypeStore::IdList* missing_id_list) {
- DFAKE_SCOPED_LOCK(push_pop_);
+ DCHECK(sequence_checker_.CalledOnValidSequence());
DCHECK(db_);
record_list->reserve(id_list.size());
leveldb::ReadOptions read_options;
@@ -186,7 +231,7 @@ ModelTypeStore::Result ModelTypeStoreBackend::ReadRecordsWithPrefix(
ModelTypeStore::Result ModelTypeStoreBackend::ReadAllRecordsWithPrefix(
const std::string& prefix,
ModelTypeStore::RecordList* record_list) {
- DFAKE_SCOPED_LOCK(push_pop_);
+ DCHECK(sequence_checker_.CalledOnValidSequence());
DCHECK(db_);
leveldb::ReadOptions read_options;
read_options.verify_checksums = true;
@@ -205,7 +250,7 @@ ModelTypeStore::Result ModelTypeStoreBackend::ReadAllRecordsWithPrefix(
ModelTypeStore::Result ModelTypeStoreBackend::WriteModifications(
std::unique_ptr<leveldb::WriteBatch> write_batch) {
- DFAKE_SCOPED_LOCK(push_pop_);
+ DCHECK(sequence_checker_.CalledOnValidSequence());
DCHECK(db_);
leveldb::Status status =
db_->Write(leveldb::WriteOptions(), write_batch.get());
@@ -263,4 +308,9 @@ void ModelTypeStoreBackend::RecordStoreInitResultHistogram(
STORE_INIT_RESULT_COUNT);
}
+// static
+bool ModelTypeStoreBackend::BackendExistsForTest(const std::string& path) {
+ return backend_map.Get().GetBackend(path) != nullptr;
+}
+
} // namespace syncer
« no previous file with comments | « components/sync/model_impl/model_type_store_backend.h ('k') | components/sync/model_impl/model_type_store_backend_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698