diff --git a/source/common/common/thread.h b/source/common/common/thread.h index 105f95ae89f6..096f228eebac 100644 --- a/source/common/common/thread.h +++ b/source/common/common/thread.h @@ -25,6 +25,8 @@ class MutexBasicLockable : public BasicLockable { bool tryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) override { return mutex_.TryLock(); } void unlock() ABSL_UNLOCK_FUNCTION() override { mutex_.Unlock(); } + void assertHeld() ABSL_ASSERT_EXCLUSIVE_LOCK(this) { mutex_.AssertHeld(); } + private: friend class CondVar; absl::Mutex mutex_; diff --git a/source/common/stats/thread_local_store.cc b/source/common/stats/thread_local_store.cc index 09e235e6ac4c..4dec99975b57 100644 --- a/source/common/stats/thread_local_store.cc +++ b/source/common/stats/thread_local_store.cc @@ -54,6 +54,7 @@ ThreadLocalStoreImpl::~ThreadLocalStoreImpl() { void ThreadLocalStoreImpl::setHistogramSettings(HistogramSettingsConstPtr&& histogram_settings) { iterateScopes([](const ScopeImplSharedPtr& scope) -> bool { + scope->parent_.lock_.assertHeld(); ASSERT(scope->centralCacheLockHeld()->histograms_.empty()); return true; }); @@ -74,6 +75,7 @@ void ThreadLocalStoreImpl::setStatsMatcher(StatsMatcherPtr&& stats_matcher) { const uint32_t first_histogram_index = deleted_histograms_.size(); iterateScopesLockHeld([this](const ScopeImplSharedPtr& scope) ABSL_EXCLUSIVE_LOCKS_REQUIRED( lock_) -> bool { + scope->parent_.lock_.assertHeld(); const CentralCacheEntrySharedPtr& central_cache = scope->centralCacheLockHeld(); removeRejectedStats(central_cache->counters_, [this](const CounterSharedPtr& counter) mutable { @@ -293,6 +295,7 @@ void ThreadLocalStoreImpl::releaseScopeCrossThread(ScopeImpl* scope) { // VirtualHosts. bool need_post = scopes_to_cleanup_.empty(); scopes_to_cleanup_.push_back(scope->scope_id_); + scope->parent_.lock_.assertHeld(); central_cache_entries_to_cleanup_.push_back(scope->centralCacheLockHeld()); lock.release(); diff --git a/source/common/stats/thread_local_store.h b/source/common/stats/thread_local_store.h index f8f27558b400..4aab7f050f1a 100644 --- a/source/common/stats/thread_local_store.h +++ b/source/common/stats/thread_local_store.h @@ -339,16 +339,16 @@ class ThreadLocalStoreImpl : Logger::Loggable, public StoreRo return iterateLockHeld(fn); } - bool iterateLockHeld(const IterateFn& fn) const { + bool iterateLockHeld(const IterateFn& fn) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(parent_.lock_) { return iterHelper(fn, centralCacheLockHeld()->counters_); } - bool iterateLockHeld(const IterateFn& fn) const { + bool iterateLockHeld(const IterateFn& fn) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(parent_.lock_) { return iterHelper(fn, centralCacheLockHeld()->gauges_); } - bool iterateLockHeld(const IterateFn& fn) const { + bool iterateLockHeld(const IterateFn& fn) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(parent_.lock_) { return iterHelper(fn, centralCacheLockHeld()->histograms_); } - bool iterateLockHeld(const IterateFn& fn) const { + bool iterateLockHeld(const IterateFn& fn) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(parent_.lock_) { return iterHelper(fn, centralCacheLockHeld()->text_readouts_); } ThreadLocalStoreImpl& store() override { return parent_; } @@ -421,7 +421,7 @@ class ThreadLocalStoreImpl : Logger::Loggable, public StoreRo // scope->central_cache_, the analysis system cannot understand that the // scope's parent_.lock_ is held, so we assert that here. const CentralCacheEntrySharedPtr& centralCacheLockHeld() const - ABSL_ASSERT_EXCLUSIVE_LOCK(parent_.lock_) { + ABSL_EXCLUSIVE_LOCKS_REQUIRED(parent_.lock_) { return central_cache_; } @@ -482,7 +482,10 @@ class ThreadLocalStoreImpl : Logger::Loggable, public StoreRo // The Store versions of iterate cover all the scopes in the store. template bool iterHelper(StatFn fn) const { return iterateScopes( - [fn](const ScopeImplSharedPtr& scope) -> bool { return scope->iterateLockHeld(fn); }); + [fn](const ScopeImplSharedPtr& scope) -> bool { + scope->parent_.lock_.assertHeld(); + return scope->iterateLockHeld(fn); + }); } std::string getTagsForName(const std::string& name, TagVector& tags) const;