Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save tvogel/f407b99b43818bb690319e8d7e9112e3 to your computer and use it in GitHub Desktop.

Select an option

Save tvogel/f407b99b43818bb690319e8d7e9112e3 to your computer and use it in GitHub Desktop.
Orthanc patch: Release large-dicom semaphore-lock directly after reading index
# HG changeset patch
# User Tilman Vogel <tilman.vogel@web.de>
# Date 1778599439 -7200
# Tue May 12 17:23:59 2026 +0200
# Node ID 738952aeb03260dca49be0cb51e05f3bbc0114af
# Parent fa7123b2930a94a4a3f0411a1af7e16a626f2c65
Release large-dicom semaphore-lock directly after reading index
... and before reading the payload from storage to improve parallelism
for "small" payloads.
diff -r fa7123b2930a -r 738952aeb032 OrthancServer/Sources/ServerContext.cpp
--- a/OrthancServer/Sources/ServerContext.cpp Tue Jan 27 20:02:51 2026 +0100
+++ b/OrthancServer/Sources/ServerContext.cpp Tue May 12 17:23:59 2026 +0200
@@ -1375,6 +1375,17 @@
std::string& attachmentId,
const std::string& instancePublicId)
{
+ std::unique_ptr<Semaphore::Locker> dummyLargeDicomLocker;
+ ReadDicom(dicom, attachmentId, instancePublicId, dummyLargeDicomLocker, 0);
+ }
+
+
+ void ServerContext::ReadDicom(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;
@@ -1388,6 +1399,11 @@
assert(attachment.GetContentType() == FileContentType_Dicom);
attachmentId = attachment.GetUuid();
+ if (attachment.GetUncompressedSize() < largeDicomThreshold)
+ {
+ largeDicomLocker.reset(NULL);
+ }
+
ReadAttachment(dicom, attachment, true /* uncompress */);
}
@@ -1399,6 +1415,17 @@
ReadDicom(dicom, attachmentId, instancePublicId);
}
+
+ void ServerContext::ReadDicom(std::string& dicom,
+ const std::string& instancePublicId,
+ std::unique_ptr<Semaphore::Locker>& largeDicomLocker,
+ std::size_t largeDicomThreshold)
+ {
+ std::string attachmentId;
+ ReadDicom(dicom, attachmentId, instancePublicId, largeDicomLocker, largeDicomThreshold);
+ }
+
+
void ServerContext::ReadDicomForHeader(std::string& dicom,
const std::string& instancePublicId)
{
@@ -1513,16 +1540,11 @@
// Throttle to avoid loading several large DICOM files simultaneously
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() < 50 * 1024 * 1024)
- {
- largeDicomLocker_.reset(NULL);
- }
-
+ context_.ReadDicom(buffer_, instancePublicId_, largeDicomLocker_, 50 * 1024 * 1024);
+
dicom_.reset(new ParsedDicomFile(buffer_));
dicomSize_ = buffer_.size();
}
diff -r fa7123b2930a -r 738952aeb032 OrthancServer/Sources/ServerContext.h
--- a/OrthancServer/Sources/ServerContext.h Tue Jan 27 20:02:51 2026 +0100
+++ b/OrthancServer/Sources/ServerContext.h Tue May 12 17:23:59 2026 +0200
@@ -400,9 +400,20 @@
const std::string& instancePublicId);
void ReadDicom(std::string& dicom,
+ const std::string& instancePublicId,
+ std::unique_ptr<Semaphore::Locker>& largeDicomLocker,
+ std::size_t largeDicomThreshold);
+
+ void ReadDicom(std::string& dicom,
std::string& attachmentId,
const std::string& instancePublicId);
+ void ReadDicom(std::string& dicom,
+ std::string& attachmentId,
+ const std::string& instancePublicId,
+ std::unique_ptr<Semaphore::Locker>& largeDicomLocker,
+ std::size_t largeDicomThreshold);
+
void ReadDicomForHeader(std::string& dicom,
const std::string& instancePublicId);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment