Mercurial > hg > orthanc
changeset 6800:7d025f650e9f
merge
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Mon, 18 May 2026 14:07:18 +0200 |
| parents | cdf8b88c60c8 (current diff) 8ac77592226e (diff) |
| children | e98c73866fcb |
| files | OrthancServer/Sources/ServerContext.cpp OrthancServer/Sources/ServerContext.h |
| diffstat | 2 files changed, 39 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancServer/Sources/ServerContext.cpp Mon May 18 14:02:50 2026 +0200 +++ b/OrthancServer/Sources/ServerContext.cpp Mon May 18 14:07:18 2026 +0200 @@ -1404,6 +1404,16 @@ std::string& attachmentId, const std::string& instancePublicId) { + std::unique_ptr<Semaphore::Locker> dummyLargeDicomLocker; // only the DicomCacheLocker uses a real largeDicomLocker_ + ReadDicomInternal(dicom, attachmentId, instancePublicId, dummyLargeDicomLocker, 0); + } + + void ServerContext::ReadDicomInternal(std::string& dicom, + std::string& attachmentId, + const std::string& instancePublicId, + std::unique_ptr<Semaphore::Locker>& largeDicomLocker, + std::size_t largeDicomThreshold) + { FileInfo attachment; int64_t revision; @@ -1417,6 +1427,11 @@ assert(attachment.GetContentType() == FileContentType_Dicom); attachmentId = attachment.GetUuid(); + if (attachment.GetUncompressedSize() < largeDicomThreshold) // release ASAP (before the read) if we don't plan to hold the lock (https://discourse.orthanc-server.org/t/patch-release-large-dicom-semaphore-lock-early-for-better-performance/6440) + { + largeDicomLocker.reset(NULL); + } + ReadAttachment(dicom, attachment, true /* uncompress */); } @@ -1428,6 +1443,15 @@ ReadDicom(dicom, attachmentId, instancePublicId); } + void ServerContext::ReadDicomInternal(std::string& dicom, + const std::string& instancePublicId, + std::unique_ptr<Semaphore::Locker>& largeDicomLocker, + std::size_t largeDicomThreshold) + { + std::string attachmentId; + ReadDicomInternal(dicom, attachmentId, instancePublicId, largeDicomLocker, largeDicomThreshold); + } + void ServerContext::ReadDicomForHeader(std::string& dicom, const std::string& instancePublicId) { @@ -1540,17 +1564,12 @@ { accessor_.reset(NULL); - // Throttle to avoid loading several large DICOM files simultaneously + // Throttle to avoid loading several large DICOM files simultaneously (since the ParsedDicomCache is 128MB, loading multiple 50MB files would throw them out directly after loading) largeDicomLocker_.reset(new Semaphore::Locker(context.largeDicomThrottler_)); - context_.ReadDicom(buffer_, instancePublicId_); - // Release the throttle if loading "small" DICOM files (under // 50MB, which is an arbitrary value) - if (buffer_.size() < static_cast<size_t>(50) * 1024 * 1024) - { - largeDicomLocker_.reset(NULL); - } + context_.ReadDicomInternal(buffer_, instancePublicId_, largeDicomLocker_, static_cast<size_t>(50) * 1024 * 1024); dicom_.reset(new ParsedDicomFile(buffer_)); dicomSize_ = buffer_.size();
--- a/OrthancServer/Sources/ServerContext.h Mon May 18 14:02:50 2026 +0200 +++ b/OrthancServer/Sources/ServerContext.h Mon May 18 14:07:18 2026 +0200 @@ -398,6 +398,19 @@ void ReadDicomAsJson(Json::Value& result, const std::string& instancePublicId); // TODO-FIND: Can this be removed? +private: + void ReadDicomInternal(std::string& dicom, + const std::string& instancePublicId, + std::unique_ptr<Semaphore::Locker>& largeDicomLocker, + std::size_t largeDicomThreshold); + + void ReadDicomInternal(std::string& dicom, + std::string& attachmentId, + const std::string& instancePublicId, + std::unique_ptr<Semaphore::Locker>& largeDicomLocker, + std::size_t largeDicomThreshold); + +public: void ReadDicom(std::string& dicom, const std::string& instancePublicId);
