# HG changeset patch # User Sebastien Jodogne # Date 1769515223 -3600 # Node ID dfb5748c820976bd0f1e323d43263d8d9a2dd45a # Parent a96b627e2723c7249a19cefef138e5b4ebdf17cc protect accesses to SharedArchive using readers-writer lock diff -r a96b627e2723 -r dfb5748c8209 OrthancFramework/Sources/Cache/SharedArchive.cpp --- a/OrthancFramework/Sources/Cache/SharedArchive.cpp Tue Jan 27 12:06:49 2026 +0100 +++ b/OrthancFramework/Sources/Cache/SharedArchive.cpp Tue Jan 27 13:00:23 2026 +0100 @@ -32,6 +32,9 @@ { void SharedArchive::RemoveInternal(const std::string& id) { + // This function assumes that "mutex_" is locked by a WriterLock, + // and that "lruMutex_" is locked + Archive::iterator it = archive_.find(id); if (it != archive_.end()) @@ -45,10 +48,9 @@ SharedArchive::Accessor::Accessor(SharedArchive& that, - const std::string& id) + const std::string& id) : + lock_(that.mutex_) { - boost::recursive_mutex::scoped_lock lock(that.mutex_); - Archive::iterator it = that.archive_.find(id); if (it == that.archive_.end()) @@ -57,7 +59,11 @@ } else { - that.lru_.MakeMostRecent(id); + { + boost::mutex::scoped_lock lock(that.lruMutex_); + that.lru_.MakeMostRecent(id); + } + item_ = it->second; } } @@ -104,7 +110,8 @@ std::string SharedArchive::Add(IDynamicObject* obj) { - boost::recursive_mutex::scoped_lock lock(mutex_); + WriterLock lock(mutex_); + boost::mutex::scoped_lock lruLock(lruMutex_); if (archive_.size() == maxSize_) { @@ -124,7 +131,9 @@ void SharedArchive::Remove(const std::string& id) { - boost::recursive_mutex::scoped_lock lock(mutex_); + WriterLock lock(mutex_); + boost::mutex::scoped_lock lruLock(lruMutex_); + RemoveInternal(id); } @@ -134,7 +143,7 @@ items.clear(); { - boost::recursive_mutex::scoped_lock lock(mutex_); + ReaderLock lock(mutex_); for (Archive::const_iterator it = archive_.begin(); it != archive_.end(); ++it) diff -r a96b627e2723 -r dfb5748c8209 OrthancFramework/Sources/Cache/SharedArchive.h --- a/OrthancFramework/Sources/Cache/SharedArchive.h Tue Jan 27 12:06:49 2026 +0100 +++ b/OrthancFramework/Sources/Cache/SharedArchive.h Tue Jan 27 13:00:23 2026 +0100 @@ -44,10 +44,15 @@ { private: typedef std::map Archive; + typedef boost::shared_lock ReaderLock; + typedef boost::unique_lock WriterLock; size_t maxSize_; - boost::recursive_mutex mutex_; + boost::shared_mutex mutex_; Archive archive_; + + // The LRU index is not protected by "mutex_", but by "lruMutex_" + boost::mutex lruMutex_; LeastRecentlyUsedIndex lru_; void RemoveInternal(const std::string& id); @@ -56,8 +61,8 @@ class ORTHANC_PUBLIC Accessor : public boost::noncopyable { private: - boost::recursive_mutex::scoped_lock lock_; - IDynamicObject* item_; + ReaderLock lock_; + IDynamicObject* item_; public: Accessor(SharedArchive& that, @@ -68,7 +73,6 @@ IDynamicObject& GetItem() const; }; - explicit SharedArchive(size_t maxSize); ~SharedArchive(); @@ -80,5 +84,3 @@ void List(std::list& items); }; } - - diff -r a96b627e2723 -r dfb5748c8209 OrthancServer/Sources/ServerJobs/ArchiveJob.cpp --- a/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp Tue Jan 27 12:06:49 2026 +0100 +++ b/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp Tue Jan 27 13:00:23 2026 +0100 @@ -1649,18 +1649,16 @@ if (key == "archive" && !mediaArchiveId_.empty()) { - SharedArchive::Accessor accessor(context_.GetMediaArchive(), mediaArchiveId_); + bool found; - if (accessor.IsValid()) { - context_.GetMediaArchive().Remove(mediaArchiveId_); - return true; + SharedArchive::Accessor accessor(context_.GetMediaArchive(), mediaArchiveId_); + found = accessor.IsValid(); } - else - { - return false; - } - } + + context_.GetMediaArchive().Remove(mediaArchiveId_); + return found; + } else { return false;