Index: services/preferences/public/cpp/persistent_pref_store_client.cc |
diff --git a/services/preferences/public/cpp/persistent_pref_store_client.cc b/services/preferences/public/cpp/persistent_pref_store_client.cc |
index 353ac4c72d3a90a62b6cb62bd2d4d37e69642123..9bcb92fb1b6e3859e745c8360fc93dea0bcf42c5 100644 |
--- a/services/preferences/public/cpp/persistent_pref_store_client.cc |
+++ b/services/preferences/public/cpp/persistent_pref_store_client.cc |
@@ -19,12 +19,14 @@ PersistentPrefStoreClient::PersistentPrefStoreClient( |
std::vector<PrefValueStore::PrefStoreType> already_connected_types) |
: connector_(std::move(connector)), |
pref_registry_(std::move(pref_registry)), |
- already_connected_types_(std::move(already_connected_types)) { |
+ already_connected_types_(std::move(already_connected_types)), |
+ weak_factory_(this) { |
DCHECK(connector_); |
} |
PersistentPrefStoreClient::PersistentPrefStoreClient( |
- mojom::PersistentPrefStoreConnectionPtr connection) { |
+ mojom::PersistentPrefStoreConnectionPtr connection) |
+ : weak_factory_(this) { |
OnConnect(std::move(connection), |
std::unordered_map<PrefValueStore::PrefStoreType, |
prefs::mojom::PrefStoreConnectionPtr>()); |
@@ -57,8 +59,8 @@ void PersistentPrefStoreClient::ReportValueChanged(const std::string& key, |
DCHECK(pref_store_); |
const base::Value* local_value = nullptr; |
GetMutableValues().Get(key, &local_value); |
- pref_store_->SetValue( |
- key, local_value ? local_value->CreateDeepCopy() : nullptr, flags); |
+ |
+ QueueWrite(key, flags); |
ReportPrefValueChanged(key); |
} |
@@ -67,7 +69,7 @@ void PersistentPrefStoreClient::SetValueSilently( |
std::unique_ptr<base::Value> value, |
uint32_t flags) { |
DCHECK(pref_store_); |
- pref_store_->SetValue(key, value->CreateDeepCopy(), flags); |
+ QueueWrite(key, flags); |
GetMutableValues().Set(key, std::move(value)); |
} |
@@ -108,6 +110,8 @@ void PersistentPrefStoreClient::ReadPrefsAsync( |
void PersistentPrefStoreClient::CommitPendingWrite() { |
DCHECK(pref_store_); |
+ if (!pending_writes_.empty()) |
+ FlushPendingWrites(); |
pref_store_->CommitPendingWrite(); |
} |
@@ -125,7 +129,7 @@ PersistentPrefStoreClient::~PersistentPrefStoreClient() { |
if (!pref_store_) |
return; |
- pref_store_->CommitPendingWrite(); |
+ CommitPendingWrite(); |
} |
void PersistentPrefStoreClient::OnConnect( |
@@ -149,4 +153,32 @@ void PersistentPrefStoreClient::OnConnect( |
} |
} |
+void PersistentPrefStoreClient::QueueWrite(const std::string& key, |
+ uint32_t flags) { |
+ if (pending_writes_.empty()) { |
+ // Use a weak pointer since a pending write should not prolong the life of |
+ // |this|. Instead, the destruction of |this| will flush any pending writes. |
+ base::ThreadTaskRunnerHandle::Get()->PostTask( |
+ FROM_HERE, base::Bind(&PersistentPrefStoreClient::FlushPendingWrites, |
+ weak_factory_.GetWeakPtr())); |
+ } |
+ pending_writes_.insert(std::make_pair(key, flags)); |
+} |
+ |
+void PersistentPrefStoreClient::FlushPendingWrites() { |
+ std::vector<mojom::PrefUpdatePtr> updates; |
+ for (const auto& pref : pending_writes_) { |
+ const base::Value* value = nullptr; |
+ if (GetValue(pref.first, &value)) { |
+ updates.push_back(mojom::PrefUpdate::New( |
+ pref.first, value->CreateDeepCopy(), pref.second)); |
+ } else { |
+ updates.push_back( |
+ mojom::PrefUpdate::New(pref.first, nullptr, pref.second)); |
+ } |
+ } |
+ pref_store_->SetValues(std::move(updates)); |
+ pending_writes_.clear(); |
+} |
+ |
} // namespace prefs |