Mercurial > hg > orthanc
changeset 5178:02c7e4aa7946
internal class DicomMap::MainDicomTagsConfiguration is now thread-safe
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sat, 25 Mar 2023 10:47:29 +0100 |
parents | 6807a2b012a0 |
children | 1e406c23b352 |
files | OrthancFramework/Sources/DicomFormat/DicomMap.cpp |
diffstat | 1 files changed, 63 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancFramework/Sources/DicomFormat/DicomMap.cpp Sat Mar 25 10:37:56 2023 +0100 +++ b/OrthancFramework/Sources/DicomFormat/DicomMap.cpp Sat Mar 25 10:47:29 2023 +0100 @@ -39,6 +39,11 @@ #include "../DicomParsing/FromDcmtkBridge.h" #endif +#if !defined(__EMSCRIPTEN__) +// Multithreading is not supported in WebAssembly +# include <boost/thread/shared_mutex.hpp> +#endif + namespace Orthanc { // WARNING: the DEFAULT list of main dicom tags below are the list as they @@ -132,9 +137,16 @@ DICOM_TAG_IMAGE_ORIENTATION_PATIENT // New in Orthanc 1.4.2 }; - class DicomMap::MainDicomTagsConfiguration + class DicomMap::MainDicomTagsConfiguration : public boost::noncopyable { private: +#if !defined(__EMSCRIPTEN__) + typedef boost::unique_lock<boost::shared_mutex> WriterLock; + typedef boost::shared_lock<boost::shared_mutex> ReaderLock; + + boost::shared_mutex mutex_; +#endif + std::set<DicomTag> patientsMainDicomTagsByLevel_; std::set<DicomTag> studiesMainDicomTagsByLevel_; std::set<DicomTag> seriesMainDicomTagsByLevel_; @@ -200,7 +212,7 @@ for (size_t i = 0; i < size; i++) { - AddMainDicomTag(tags[i], level); + AddMainDicomTagInternal(tags[i], level); } } @@ -225,6 +237,22 @@ } } + void AddMainDicomTagInternal(const DicomTag& tag, + ResourceType level) + { + std::set<DicomTag>& existingLevelTags = GetMainDicomTagsByLevelInternal(level); + + if (existingLevelTags.find(tag) != existingLevelTags.end()) + { + throw OrthancException(ErrorCode_MainDicomTagsMultiplyDefined, tag.Format() + " is already defined"); + } + + existingLevelTags.insert(tag); + allMainDicomTags_.insert(tag); + + signatures_[level] = ComputeSignature(GetMainDicomTagsByLevelInternal(level)); + } + public: // Singleton pattern static MainDicomTagsConfiguration& GetInstance() @@ -235,6 +263,10 @@ void ResetDefaultMainDicomTags() { +#if !defined(__EMSCRIPTEN__) + WriterLock lock(mutex_); +#endif + patientsMainDicomTagsByLevel_.clear(); studiesMainDicomTagsByLevel_.clear(); seriesMainDicomTagsByLevel_.clear(); @@ -257,54 +289,68 @@ void AddMainDicomTag(const DicomTag& tag, ResourceType level) { - std::set<DicomTag>& existingLevelTags = GetMainDicomTagsByLevelInternal(level); +#if !defined(__EMSCRIPTEN__) + WriterLock lock(mutex_); +#endif - if (existingLevelTags.find(tag) != existingLevelTags.end()) - { - throw OrthancException(ErrorCode_MainDicomTagsMultiplyDefined, tag.Format() + " is already defined"); - } - - existingLevelTags.insert(tag); - allMainDicomTags_.insert(tag); - - std::set<DicomTag> mainDicomTags; - GetMainDicomTagsByLevel(mainDicomTags, level); - signatures_[level] = ComputeSignature(mainDicomTags); + AddMainDicomTagInternal(tag, level); } - void GetAllMainDicomTags(std::set<DicomTag>& target) const + void GetAllMainDicomTags(std::set<DicomTag>& target) { +#if !defined(__EMSCRIPTEN__) + ReaderLock lock(mutex_); +#endif + target = allMainDicomTags_; } void GetMainDicomTagsByLevel(std::set<DicomTag>& target, ResourceType level) { +#if !defined(__EMSCRIPTEN__) + ReaderLock lock(mutex_); +#endif + target = GetMainDicomTagsByLevelInternal(level); } std::string GetMainDicomTagsSignature(ResourceType level) { +#if !defined(__EMSCRIPTEN__) + ReaderLock lock(mutex_); +#endif + assert(signatures_.find(level) != signatures_.end()); - return signatures_[level]; } std::string GetDefaultMainDicomTagsSignature(ResourceType level) { +#if !defined(__EMSCRIPTEN__) + ReaderLock lock(mutex_); +#endif + assert(defaultSignatures_.find(level) != defaultSignatures_.end()); - return defaultSignatures_[level]; } bool IsMainDicomTag(const DicomTag& tag) { +#if !defined(__EMSCRIPTEN__) + ReaderLock lock(mutex_); +#endif + return allMainDicomTags_.find(tag) != allMainDicomTags_.end(); } bool IsMainDicomTag(const DicomTag& tag, ResourceType level) { +#if !defined(__EMSCRIPTEN__) + ReaderLock lock(mutex_); +#endif + const std::set<DicomTag>& mainDicomTags = GetMainDicomTagsByLevelInternal(level); return mainDicomTags.find(tag) != mainDicomTags.end(); }