diff --git a/sharing/internal/test/BUILD b/sharing/internal/test/BUILD index 536d5827..ed62a885 100644 --- a/sharing/internal/test/BUILD +++ b/sharing/internal/test/BUILD @@ -46,10 +46,12 @@ cc_library( "//sharing/internal/public:logging", "//sharing/internal/public:types", "//sharing/proto:share_cc_proto", + "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/status", "@com_google_absl//absl/strings", + "@com_google_absl//absl/synchronization", "@com_google_absl//absl/time", "@com_google_absl//absl/types:span", ], diff --git a/sharing/internal/test/fake_preference_manager.cc b/sharing/internal/test/fake_preference_manager.cc index 9f3e9966..d09b7f30 100644 --- a/sharing/internal/test/fake_preference_manager.cc +++ b/sharing/internal/test/fake_preference_manager.cc @@ -21,7 +21,9 @@ #include #include +#include "absl/container/flat_hash_map.h" #include "absl/strings/string_view.h" +#include "absl/synchronization/mutex.h" #include "absl/time/time.h" #include "absl/types/span.h" #include "sharing/internal/api/private_certificate_data.h" @@ -31,22 +33,26 @@ using ::nearby::sharing::api::PrivateCertificateData; template void FakePreferenceManager::SetValue(absl::string_view key, T value) { - if (values_.contains(key)) { - const Data& data = values_.at(key); - if (std::holds_alternative(data)) { - if (std::get(data) == value) { - return; + { + absl::MutexLock lock(&mutex_); + if (values_.contains(key)) { + const Data& data = values_.at(key); + if (std::holds_alternative(data)) { + if (std::get(data) == value) { + return; + } } + values_.erase(key); } - values_.erase(key); + values_.emplace(key, value); } - values_.emplace(key, value); NotifyPreferenceChanged(key); } template T FakePreferenceManager::GetValue(absl::string_view key, const T& default_value) const { + absl::MutexLock lock(&mutex_); if (values_.contains(key)) { const Data& data = values_.at(key); if (std::holds_alternative(data)) { @@ -64,19 +70,23 @@ void FakePreferenceManager::SetArray(absl::string_view key, for (T value : values) { data.push_back(value); } - if (arrays_.contains(key)) { - if (data == arrays_.at(key)) { - return; + { + absl::MutexLock lock(&mutex_); + if (arrays_.contains(key)) { + if (data == arrays_.at(key)) { + return; + } + arrays_.erase(key); } - arrays_.erase(key); + arrays_.emplace(key, data); } - arrays_.emplace(key, data); NotifyPreferenceChanged(key); } template std::vector FakePreferenceManager::GetArray( absl::string_view key, absl::Span default_value) const { + absl::MutexLock lock(&mutex_); if (arrays_.contains(key)) { const std::vector& data = arrays_.at(key); std::vector result; @@ -94,23 +104,27 @@ std::vector FakePreferenceManager::GetArray( template void FakePreferenceManager::SetDictionaryValue( absl::string_view key, absl::string_view dictionary_item, T value) { - auto& dictionary = dictionaries_[key]; - if (dictionary.contains(dictionary_item)) { - const Data& data = dictionary.at(dictionary_item); - if (std::holds_alternative(data)) { - if (std::get(data) == value) { - return; + { + absl::MutexLock lock(&mutex_); + auto& dictionary = dictionaries_[key]; + if (dictionary.contains(dictionary_item)) { + const Data& data = dictionary.at(dictionary_item); + if (std::holds_alternative(data)) { + if (std::get(data) == value) { + return; + } } + dictionary.erase(dictionary_item); } - dictionary.erase(dictionary_item); + dictionary.emplace(dictionary_item, value); } - dictionary.emplace(dictionary_item, value); NotifyPreferenceChanged(key); } template std::optional FakePreferenceManager::GetDictionaryValue( absl::string_view key, absl::string_view dictionary_item) const { + absl::MutexLock lock(&mutex_); if (!dictionaries_.contains(key)) { return std::nullopt; } @@ -168,6 +182,7 @@ void FakePreferenceManager::SetStringArray( void FakePreferenceManager::SetPrivateCertificateArray( absl::string_view key, absl::Span value) { + absl::MutexLock lock(&mutex_); if (certs_.contains(key)) { certs_.erase(key); } @@ -178,6 +193,7 @@ void FakePreferenceManager::SetPrivateCertificateArray( void FakePreferenceManager::SetCertificateExpirationArray( absl::string_view key, absl::Span> value) { + absl::MutexLock lock(&mutex_); if (cert_expirations_.contains(key)) { cert_expirations_.erase(key); } @@ -208,11 +224,14 @@ void FakePreferenceManager::SetDictionaryStringValue( void FakePreferenceManager::RemoveDictionaryItem( absl::string_view key, absl::string_view dictionary_item) { - if (!dictionaries_.contains(key)) { - return; + { + absl::MutexLock lock(&mutex_); + if (!dictionaries_.contains(key)) { + return; + } + auto& dictionary = dictionaries_[key]; + dictionary.erase(dictionary_item); } - auto& dictionary = dictionaries_[key]; - dictionary.erase(dictionary_item); NotifyPreferenceChanged(key); } @@ -264,6 +283,7 @@ std::vector FakePreferenceManager::GetStringArray( std::vector FakePreferenceManager::GetPrivateCertificateArray(absl::string_view key) const { + absl::MutexLock lock(&mutex_); if (certs_.contains(key)) { return certs_.at(key); } @@ -273,6 +293,7 @@ FakePreferenceManager::GetPrivateCertificateArray(absl::string_view key) const { std::vector> FakePreferenceManager::GetCertificateExpirationArray( absl::string_view key) const { + absl::MutexLock lock(&mutex_); if (cert_expirations_.contains(key)) { return cert_expirations_.at(key); } @@ -300,14 +321,23 @@ std::optional FakePreferenceManager::GetDictionaryStringValue( } void FakePreferenceManager::Remove(absl::string_view key) { - values_.erase(key); - arrays_.erase(key); - dictionaries_.erase(key); + { + absl::MutexLock lock(&mutex_); + values_.erase(key); + arrays_.erase(key); + dictionaries_.erase(key); + } NotifyPreferenceChanged(key); } void FakePreferenceManager::NotifyPreferenceChanged(absl::string_view key) { - for (const auto& observer : observers_) { + absl::flat_hash_map> + observers; + { + absl::MutexLock lock(&mutex_); + observers = observers_; + } + for (const auto& observer : observers) { observer.second(key); } } @@ -315,10 +345,12 @@ void FakePreferenceManager::NotifyPreferenceChanged(absl::string_view key) { void FakePreferenceManager::AddObserver( absl::string_view name, std::function observer) { + absl::MutexLock lock(&mutex_); observers_.emplace(name, observer); } void FakePreferenceManager::RemoveObserver(absl::string_view name) { + absl::MutexLock lock(&mutex_); observers_.erase(name); } diff --git a/sharing/internal/test/fake_preference_manager.h b/sharing/internal/test/fake_preference_manager.h index 709e4d27..c1a3fc0f 100644 --- a/sharing/internal/test/fake_preference_manager.h +++ b/sharing/internal/test/fake_preference_manager.h @@ -23,8 +23,10 @@ #include #include +#include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" #include "absl/strings/string_view.h" +#include "absl/synchronization/mutex.h" #include "absl/time/time.h" #include "absl/types/span.h" #include "sharing/internal/api/preference_manager.h" @@ -116,36 +118,45 @@ class FakePreferenceManager : public nearby::sharing::api::PreferenceManager { private: typedef std::variant Data; - template void SetValue(absl::string_view key, T value); template - T GetValue(absl::string_view key, const T& default_value) const; + void SetValue(absl::string_view key, T value) ABSL_LOCKS_EXCLUDED(mutex_); template - void SetArray(absl::string_view key, absl::Span values); + T GetValue(absl::string_view key, const T& default_value) const + ABSL_LOCKS_EXCLUDED(mutex_); + template + void SetArray(absl::string_view key, absl::Span values) + ABSL_LOCKS_EXCLUDED(mutex_); template std::vector GetArray(absl::string_view key, - absl::Span default_value) const; + absl::Span default_value) const + ABSL_LOCKS_EXCLUDED(mutex_); template void SetDictionaryValue(absl::string_view key, - absl::string_view dictionary_item, T value); + absl::string_view dictionary_item, T value) + ABSL_LOCKS_EXCLUDED(mutex_); template std::optional GetDictionaryValue(absl::string_view key, - absl::string_view dictionary_item) const; + absl::string_view dictionary_item) const + ABSL_LOCKS_EXCLUDED(mutex_); - void NotifyPreferenceChanged(absl::string_view key); + void NotifyPreferenceChanged(absl::string_view key) + ABSL_LOCKS_EXCLUDED(mutex_); - absl::flat_hash_map values_; + mutable absl::Mutex mutex_; + absl::flat_hash_map values_ ABSL_GUARDED_BY(mutex_); absl::flat_hash_map> - dictionaries_; - absl::flat_hash_map> arrays_; + dictionaries_ ABSL_GUARDED_BY(mutex_); + absl::flat_hash_map> arrays_ + ABSL_GUARDED_BY(mutex_); absl::flat_hash_map> - certs_; + certs_ ABSL_GUARDED_BY(mutex_); absl::flat_hash_map>> - cert_expirations_; + cert_expirations_ ABSL_GUARDED_BY(mutex_); absl::flat_hash_map> - observers_; + observers_ ABSL_GUARDED_BY(mutex_); }; } // namespace nearby