From: Kefu Chai Date: Thu, 2 Jul 2026 00:50:10 +0000 (+0800) Subject: common/web_cache: use ceph::shared_mutex instead of std::shared_mutex X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b1345f257619a654cf0b955511f3883d8e95bd67;p=ceph.git common/web_cache: use ceph::shared_mutex instead of std::shared_mutex WebCache declared its cache lock as a raw std::shared_mutex, bypassing the project's ceph::shared_mutex alias that every other rwlock user goes through (OSD::map_lock, TrackedOp::lock, ...). Align it with that convention: use ceph::make_shared_mutex() to construct the member, and drop the explicit template argument from each std::shared_lock/lock_guard so they deduce whichever type ceph::shared_mutex resolves to. This is idiom alignment only. The preceding commit fixes the Windows CI timeout; this one does not touch it. ceph::shared_mutex only differs from std::shared_mutex in debug builds, where it becomes ceph::shared_mutex_debug for lockdep tracking. On the mingw-llvm release build that times out unittest_web_cache, it still resolves straight to libc++'s std::shared_mutex. The O(N^2) writer-wakeup behavior under heavy exclusive-lock contention is unchanged. Verified locally: unittest_web_cache builds and passes, exercising the debug ceph::shared_mutex_debug path. Signed-off-by: Kefu Chai --- diff --git a/src/common/web_cache.h b/src/common/web_cache.h index 97c2e9dfb74..901bc878e7b 100644 --- a/src/common/web_cache.h +++ b/src/common/web_cache.h @@ -30,6 +30,7 @@ #include #include "common/ceph_context.h" +#include "common/ceph_mutex.h" #include "common/ceph_time.h" #include "include/ceph_assert.h" #include "include/common_fwd.h" @@ -129,7 +130,8 @@ class WebCache { std::unordered_map _lookup; SieveQueue _sieve_queue; Node* _sieve_hand; - mutable std::shared_mutex _cache_mutex; + mutable ceph::shared_mutex _cache_mutex = + ceph::make_shared_mutex("WebCache::_cache_mutex"); protected: // sieve_evict removes the next node using the SIEVE algorithm from @@ -218,7 +220,7 @@ class WebCache { friend std::ostream& operator<<( std::ostream& os, const WebCache& cache) { - std::shared_lock lock(cache._cache_mutex); + std::shared_lock lock(cache._cache_mutex); const auto now = ceph::real_clock::now(); os << "$" << cache._name << "["; @@ -354,14 +356,14 @@ PerfCounters* WebCache::initialize_perf_counters( template size_t WebCache::size() const { - std::shared_lock lock(_cache_mutex); + std::shared_lock lock(_cache_mutex); ceph_assert(_lookup.size() == _sieve_queue.size()); return _lookup.size(); } template size_t WebCache::clear() { - std::lock_guard lock(_cache_mutex); + std::lock_guard lock(_cache_mutex); perf_inc(Metric::clear); const size_t size_before = _sieve_queue.size(); _sieve_queue.clear(); @@ -378,7 +380,7 @@ template ceph::real_time WebCache::add(const Key& key, ValuePtr value) { // cache hit - fast under read lock { - std::shared_lock lock(_cache_mutex); + std::shared_lock lock(_cache_mutex); if (auto search = _lookup.find(key); search != _lookup.end()) { perf_inc(Metric::hit); search->second.visited = true; @@ -387,7 +389,7 @@ ceph::real_time WebCache::add(const Key& key, ValuePtr value) { } // miss, take unique lock { - std::lock_guard lock(_cache_mutex); + std::lock_guard lock(_cache_mutex); return insert_or_existing_unmutexed(key, value).expires_at; } } @@ -396,7 +398,7 @@ template WebCache::ValuePtr WebCache::lookup_or( const Key& key, ValuePtr new_val) { { - std::shared_lock cache_lock(_cache_mutex); + std::shared_lock cache_lock(_cache_mutex); auto maybe_value = lookup_unmutexed(key); if (maybe_value.has_value()) { perf_inc(Metric::hit); @@ -406,7 +408,7 @@ WebCache::ValuePtr WebCache::lookup_or( // miss, take unique lock { - std::lock_guard lock(_cache_mutex); + std::lock_guard lock(_cache_mutex); return insert_or_existing_unmutexed(key, new_val).value; } } @@ -414,7 +416,7 @@ WebCache::ValuePtr WebCache::lookup_or( template bool WebCache::update_ttl_if( const Key& key, const ValuePtr& val, ceph::timespan new_ttl) { - std::lock_guard lock(_cache_mutex); + std::lock_guard lock(_cache_mutex); if (auto search = _lookup.find(key); (search != _lookup.end() && search->second.value == val)) { search->second.expires_at = ceph::real_clock::now() + new_ttl; @@ -426,7 +428,7 @@ bool WebCache::update_ttl_if( template bool WebCache::remove_if( const Key& key, const ValuePtr& expected_val) { - std::lock_guard lock(_cache_mutex); + std::lock_guard lock(_cache_mutex); if (auto search = _lookup.find(key); (search != _lookup.end() && search->second.value == expected_val)) { auto [_, hand_moved] = @@ -500,7 +502,7 @@ WebCache::sieve_remove_unmutexed( template std::optional::ValuePtr> WebCache::lookup(const Key& key) { - std::shared_lock lock(_cache_mutex); + std::shared_lock lock(_cache_mutex); auto result = lookup_unmutexed(key); if (result.has_value()) { perf_inc(Metric::hit); @@ -537,7 +539,7 @@ typename WebCache::Node* WebCache::sieve_expire_erase_un template size_t WebCache::expire_erase() { - std::lock_guard lock(_cache_mutex); + std::lock_guard lock(_cache_mutex); const auto expiration_cutoff = ceph::real_clock::now(); const auto lookup_size_before = _lookup.size(); SieveQueue expired;