Fixed Stat cache expire check processing (#2708)

This commit is contained in:
Takeshi Nakatani
2025-10-04 02:20:07 +09:00
committed by GitHub
parent 4513e4f700
commit 735fe9352a
2 changed files with 33 additions and 2 deletions

View File

@ -871,12 +871,42 @@ bool DirStatCache::isRemovableHasLock()
}
std::lock_guard<std::mutex> dircachelock(dir_cache_lock);
if(!children.empty()){
if(HasExistedChildHasLock()){
return false;
}
return true;
}
bool DirStatCache::HasExistedChildHasLock()
{
// [FIXME]
// This for statement will result in an error saying that it can be
// replaced with std::any_of using clang-tidy.
// However, if we replace this loop with std::any_of as shown below,
// an error will occur in thread_safety.
//
// std::any_of(children.begin(), children.end(), [](const auto& pair){ return !pair.second->isNegativeHasLock(); });
//
// This is because that when using as std::any_of algorithms with
// lambda expressions, static analysis assumes that "the lambda may
// be called outside the scope of the caller."
// As a result, it concludes that there is no guarantee that the
// mutex is held within the lambda (a limitation of the analysis).
//
// Therefore, until this false positive is resolved, we use
// NOLINTNEXTLINE(readability-use-anyofallof) to avoid clang-tidy
// errors.
//
// NOLINTNEXTLINE(readability-use-anyofallof)
for(const auto& pair: children){
if(!pair.second->isNegativeHasLock()){
return true;
}
}
return false;
}
bool DirStatCache::AddHasLock(const std::string& strpath, const struct stat* pstat, const headers_t* pmeta, objtype_t type, bool is_notruncate)
{
// Check size
@ -1168,7 +1198,7 @@ bool DirStatCache::IsExpiredHasLock()
}
std::lock_guard<std::mutex> dircachelock(dir_cache_lock);
if(!HasStatHasLock() && !HasMetaHasLock() && children.empty()){
if(!HasStatHasLock() && !HasMetaHasLock() && !HasExistedChildHasLock()){
// this cache is empty
return true;
}

View File

@ -253,6 +253,7 @@ class DirStatCache : public StatCacheNode
bool ClearHasLock() override REQUIRES(StatCacheNode::cache_lock);
bool RemoveChildHasLock(const std::string& strpath) override REQUIRES(StatCacheNode::cache_lock);
bool isRemovableHasLock() override REQUIRES(StatCacheNode::cache_lock);
bool HasExistedChildHasLock() REQUIRES(StatCacheNode::cache_lock, dir_cache_lock);
bool AddHasLock(const std::string& strpath, const struct stat* pstat, const headers_t* pmeta, objtype_t type, bool is_notruncate) override REQUIRES(StatCacheNode::cache_lock);