Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package orthanc-dicomweb for 
openSUSE:Factory checked in at 2025-12-10 15:33:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/orthanc-dicomweb (Old)
 and      /work/SRC/openSUSE:Factory/.orthanc-dicomweb.new.1939 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "orthanc-dicomweb"

Wed Dec 10 15:33:52 2025 rev:22 rq:1321935 version:1.22

Changes:
--------
--- /work/SRC/openSUSE:Factory/orthanc-dicomweb/orthanc-dicomweb.changes        
2025-09-11 14:47:08.459581737 +0200
+++ 
/work/SRC/openSUSE:Factory/.orthanc-dicomweb.new.1939/orthanc-dicomweb.changes  
    2025-12-10 15:34:34.808507354 +0100
@@ -1,0 +2,10 @@
+Tue Dec  9 10:00:46 UTC 2025 - Axel Braun <[email protected]>
+
+- version 1.22
+  * framework2.diff added for compatibilty with Orthanc framework <= 1.12.10
+  * Fixed a possible deadlock when using "WadoRsLoaderThreadsCount" > 1 when 
the HTTP
+    client disconnects while downloading the response.
+  * Fixed "Success: Success" errors when trying to send resources 
synchronously to a remote DICOMweb
+    server while the Orthanc job engine was busy with other tasks.
+
+-------------------------------------------------------------------

Old:
----
  OrthancDicomWeb-1.21.tar.gz

New:
----
  OrthancDicomWeb-1.22.tar.gz
  framework2.diff

----------(New B)----------
  New:- version 1.22
  * framework2.diff added for compatibilty with Orthanc framework <= 1.12.10
  * Fixed a possible deadlock when using "WadoRsLoaderThreadsCount" > 1 when 
the HTTP
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ orthanc-dicomweb.spec ++++++
--- /var/tmp/diff_new_pack.qsI17D/_old  2025-12-10 15:34:35.684544416 +0100
+++ /var/tmp/diff_new_pack.qsI17D/_new  2025-12-10 15:34:35.688544585 +0100
@@ -21,7 +21,7 @@
 Summary:        WebViewer plugin for Orthanc
 License:        AGPL-3.0-or-later
 Group:          Productivity/Graphics/Viewers
-Version:        1.21
+Version:        1.22
 Release:        0
 URL:            https://orthanc-server.com
 Source0:        
https://orthanc.uclouvain.be/downloads/sources/%{name}/OrthancDicomWeb-%{version}.tar.gz
@@ -36,6 +36,7 @@
 Source9:        orthanc-dicomweb-readme.SUSE
 Source10:       dicomweb.json
 Patch0:         framework.diff
+Patch1:         framework2.diff
 
 BuildRequires:  cmake
 BuildRequires:  e2fsprogs-devel
@@ -44,6 +45,7 @@
 %else
 BuildRequires:  gcc-c++
 %endif
+BuildRequires:  bsdtar
 BuildRequires:  googletest-devel
 BuildRequires:  jsoncpp-devel
 BuildRequires:  libboost_date_time-devel >= 1.66
@@ -80,6 +82,9 @@
 cd ..
 
 %build
+
+dir %{buildroot}
+
 %if 0%{?suse_version} == 1500 && 0%{?sle_version} > 150200
 export CC=gcc-13
 export CXX=g++-13

++++++ OrthancDicomWeb-1.21.tar.gz -> OrthancDicomWeb-1.22.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OrthancDicomWeb-1.21/.hg_archival.txt 
new/OrthancDicomWeb-1.22/.hg_archival.txt
--- old/OrthancDicomWeb-1.21/.hg_archival.txt   2025-08-14 16:38:00.000000000 
+0200
+++ new/OrthancDicomWeb-1.22/.hg_archival.txt   2025-12-02 17:16:34.000000000 
+0100
@@ -1,6 +1,6 @@
 repo: d5f45924411123cfd02d035fd50b8e37536eadef
-node: 00cae2648bcb72d3ff12e6244ca63a2bc467b935
-branch: OrthancDicomWeb-1.21
+node: 1174d2027f6a4499996100f16bb2ad64c3d69802
+branch: OrthancDicomWeb-1.22
 latesttag: null
-latesttagdistance: 635
-changessincelatesttag: 685
+latesttagdistance: 648
+changessincelatesttag: 700
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OrthancDicomWeb-1.21/CMakeLists.txt 
new/OrthancDicomWeb-1.22/CMakeLists.txt
--- old/OrthancDicomWeb-1.21/CMakeLists.txt     2025-08-14 16:38:00.000000000 
+0200
+++ new/OrthancDicomWeb-1.22/CMakeLists.txt     2025-12-02 17:16:34.000000000 
+0100
@@ -19,17 +19,17 @@
 # along with this program. If not, see <http://www.gnu.org/licenses/>.
 
 
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 2.8...4.0)
 
 project(OrthancDicomWeb)
 
-set(ORTHANC_DICOM_WEB_VERSION "1.21")
+set(ORTHANC_DICOM_WEB_VERSION "1.22")
 
 if (ORTHANC_DICOM_WEB_VERSION STREQUAL "mainline")
   set(ORTHANC_FRAMEWORK_DEFAULT_VERSION "mainline")
   set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "hg")
 else()
-  set(ORTHANC_FRAMEWORK_DEFAULT_VERSION "1.12.5")
+  set(ORTHANC_FRAMEWORK_DEFAULT_VERSION "e0979326ac53")  # while waiting for 
1.12.11
   set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "web")
 endif()
 
@@ -60,7 +60,13 @@
 
 if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "system")
   if (ORTHANC_FRAMEWORK_USE_SHARED)
-    include(FindBoost)
+    # https://cmake.org/cmake/help/latest/policy/CMP0167.html
+    if (CMAKE_VERSION VERSION_GREATER "3.30")
+      find_package(Boost CONFIG)
+    else()
+      include(FindBoost)
+    endif()
+
     find_package(Boost COMPONENTS regex thread)
     
     if (NOT Boost_FOUND)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OrthancDicomWeb-1.21/NEWS 
new/OrthancDicomWeb-1.22/NEWS
--- old/OrthancDicomWeb-1.21/NEWS       2025-08-14 16:38:00.000000000 +0200
+++ new/OrthancDicomWeb-1.22/NEWS       2025-12-02 17:16:34.000000000 +0100
@@ -1,3 +1,12 @@
+Version 1.22 (2025-12-02)
+=========================
+
+* Fixed a possible deadlock when using "WadoRsLoaderThreadsCount" > 1 when the 
HTTP
+  client disconnects while downloading the response.
+* Fixed "Success: Success" errors when trying to send resources synchronously 
to a remote DICOMweb
+  server while the Orthanc job engine was busy with other tasks.
+
+
 Version 1.21 (2025-08-14)
 =========================
 
@@ -9,7 +18,8 @@
   only showing the time required to execute a WADO-RS query.  For example:
   WADO-RS: elapsed: 26106623 us, rate: 14.86 instances/s, 155.23Mbps
 * Fix false errors logs generated e.g when OHIF requests the 
/dicom-web/studies/../metadata route:
-  "dicom-web:/Configuration.cpp:643] Unsupported return MIME type: 
application/dicom+json, multipart/related; type=application/octet-stream; 
transfer-syntax=*, will return DICOM+JSON"
+  "dicom-web:/Configuration.cpp:643] Unsupported return MIME type: 
application/dicom+json,
+  multipart/related; type=application/octet-stream; transfer-syntax=*, will 
return DICOM+JSON"
 
 
 Version 1.20 (2025-05-12)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OrthancDicomWeb-1.21/Plugin/Plugin.cpp 
new/OrthancDicomWeb-1.22/Plugin/Plugin.cpp
--- old/OrthancDicomWeb-1.21/Plugin/Plugin.cpp  2025-08-14 16:38:00.000000000 
+0200
+++ new/OrthancDicomWeb-1.22/Plugin/Plugin.cpp  2025-12-02 17:16:34.000000000 
+0100
@@ -747,7 +747,10 @@
         std::string publicUrlRoot = 
OrthancPlugins::Configuration::GetPublicRoot();
         LOG(WARNING) << "DICOMweb public root: " << publicUrlRoot;
 
-        LOG(WARNING) << "The DICOMWeb plugin will use " << 
(OrthancPlugins::Configuration::GetWadoRsLoaderThreadsCount() == 0 ? 1 : 
OrthancPlugins::Configuration::GetWadoRsLoaderThreadsCount()) << " threads to 
load DICOM files for WADO-RS queries";
+        LOG(WARNING) << "The DICOMweb plugin will use "
+                     << 
(OrthancPlugins::Configuration::GetWadoRsLoaderThreadsCount() == 0 ? 1 :
+                         
OrthancPlugins::Configuration::GetWadoRsLoaderThreadsCount())
+                     << " threads to load DICOM files for WADO-RS queries";
       }
       else
       {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OrthancDicomWeb-1.21/Plugin/WadoRs.cpp 
new/OrthancDicomWeb-1.22/Plugin/WadoRs.cpp
--- old/OrthancDicomWeb-1.21/Plugin/WadoRs.cpp  2025-08-14 16:38:00.000000000 
+0200
+++ new/OrthancDicomWeb-1.22/Plugin/WadoRs.cpp  2025-12-02 17:16:34.000000000 
+0100
@@ -32,7 +32,7 @@
 #include <Toolbox.h>
 #include <SerializationToolbox.h>
 #include <MultiThreading/SharedMessageQueue.h>
-#include <MultiThreading/Semaphore.h>
+#include <MultiThreading/BlockingSharedMessageQueue.h>
 #include <Compression/GzipCompressor.h>
 
 #include <memory>
@@ -449,16 +449,16 @@
 
   Orthanc::SharedMessageQueue         instancesToPreload_;
 
-  Orthanc::SharedMessageQueue         loadedInstances_;
+  Orthanc::BlockingSharedMessageQueue loadedInstances_;
 
-  Orthanc::Semaphore                  bufferSemaphore_;
+  bool                                loadersShouldStop_;
 
 public:
   ThreadedInstanceLoader(size_t threadCount, bool transcode, 
Orthanc::DicomTransferSyntax transferSyntax)
   : InstanceLoader(transcode, transferSyntax),
     instancesToPreload_(0),
-    loadedInstances_(0),
-    bufferSemaphore_(3*threadCount) // to limit the number of loaded instances 
in memory
+    loadedInstances_(3*threadCount), // to limit the number of loaded 
instances in memory
+    loadersShouldStop_(false)
   {
     for (size_t i = 0; i < threadCount; i++)
     {
@@ -473,21 +473,32 @@
 
   void Clear()
   {
-    for (size_t i = 0; i < threads_.size(); i++)
+    if (threads_.size() > 0)
     {
-      instancesToPreload_.Enqueue(NULL);
-    }
+      loadersShouldStop_ = true; // not need to protect this by a mutex.  This 
is the only "writer" and all loaders are "readers"
 
-    for (size_t i = 0; i < threads_.size(); i++)
-    {
-      if (threads_[i]->joinable())
+      LOG(INFO) << "Waiting for loader threads to complete";
+
+      // unlock the loaders if they are waiting on this message queue (this 
happens when the job completes sucessfully)
+      for (size_t i = 0; i < threads_.size(); i++)
       {
-        threads_[i]->join();
+        instancesToPreload_.Enqueue(NULL);
       }
-      delete threads_[i];
-    }
 
-    threads_.clear();
+
+      for (size_t i = 0; i < threads_.size(); i++)
+      {
+        if (threads_[i]->joinable())
+        {
+          threads_[i]->join();
+        }
+        delete threads_[i];
+      }
+
+      threads_.clear();
+
+      LOG(INFO) << "Waiting for loader threads to complete - done";
+    }
   }
 
   static void PreloaderWorkerThread(ThreadedInstanceLoader* that)
@@ -495,20 +506,20 @@
     static uint16_t threadCounter = 0;
     Orthanc::Logging::SetCurrentThreadName(std::string("WADO-LOAD-") + 
boost::lexical_cast<std::string>(threadCounter++));
 
+    LOG(INFO) << "Loader thread has started";
+
     while (true)
     {
-      std::unique_ptr<InstanceToPreload> 
instanceToPreload(dynamic_cast<InstanceToPreload*>(that->instancesToPreload_.Dequeue(0)));
-      if (instanceToPreload.get() == NULL)  // that's the signal to exit the 
thread
+      std::unique_ptr<InstanceToPreload> 
instancesToPreload(dynamic_cast<InstanceToPreload*>(that->instancesToPreload_.Dequeue(0)));
+      if (instancesToPreload.get() == NULL || that->loadersShouldStop_)  // 
that's the signal to exit the thread
       {
+        LOG(INFO) << "Loader thread has completed";
         return;
       }
       
-      // wait for the consumers, no need to accumulate instances in memory if 
loaders are faster than writers
-      that->bufferSemaphore_.Acquire();
-
       try
       {
-        std::unique_ptr<OrthancPlugins::DicomInstance> 
dicom(that->GetAndTranscodeDicom(instanceToPreload.get()));
+        std::unique_ptr<OrthancPlugins::DicomInstance> 
dicom(that->GetAndTranscodeDicom(instancesToPreload.get()));
         that->loadedInstances_.Enqueue(new LoadedInstance(dicom.release()));
       }
       catch (Orthanc::OrthancException& e)
@@ -521,7 +532,6 @@
         LOG(ERROR) << "Unknown error while loading instances ";
         that->loadedInstances_.Enqueue(NULL);
       }
-
     }
   }
 
@@ -534,16 +544,13 @@
   {
     std::unique_ptr<LoadedInstance> 
loadedInstance(dynamic_cast<LoadedInstance*>(loadedInstances_.Dequeue(0)));
     
-    // unlock preloader threads to buffer the following instances
-    bufferSemaphore_.Release();
-
     if (loadedInstance.get() != NULL)
     {
       return loadedInstance->ReleaseInstance();
     }
     else
     {
-      return NULL;
+      return NULL; // happens when the loader threads are exiting
     }
   }
 };
@@ -1685,6 +1692,9 @@
 
 void InstanceWorkerThread(InstanceWorkerData* data)
 {
+  static uint16_t threadCounter = 0;
+  Orthanc::Logging::SetCurrentThreadName(std::string("DW-META-") + 
boost::lexical_cast<std::string>(threadCounter++));
+
   while (true)
   {
     try
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/OrthancDicomWeb-1.21/Resources/Orthanc/CMake/AutoGeneratedCode.cmake 
new/OrthancDicomWeb-1.22/Resources/Orthanc/CMake/AutoGeneratedCode.cmake
--- old/OrthancDicomWeb-1.21/Resources/Orthanc/CMake/AutoGeneratedCode.cmake    
2025-08-14 16:38:00.000000000 +0200
+++ new/OrthancDicomWeb-1.22/Resources/Orthanc/CMake/AutoGeneratedCode.cmake    
2025-12-02 17:16:34.000000000 +0100
@@ -20,7 +20,7 @@
 # <http://www.gnu.org/licenses/>.
 
 
-set(EMBED_RESOURCES_PYTHON "${CMAKE_CURRENT_LIST_DIR}/../EmbedResources.py"
+set(EMBED_RESOURCES_PYTHON "${CMAKE_CURRENT_LIST_DIR}/EmbedResources.py"
   CACHE INTERNAL "Path to the EmbedResources.py script from Orthanc")
 set(AUTOGENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/AUTOGENERATED")
 set(AUTOGENERATED_SOURCES)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/OrthancDicomWeb-1.21/Resources/Orthanc/CMake/Compiler.cmake 
new/OrthancDicomWeb-1.22/Resources/Orthanc/CMake/Compiler.cmake
--- old/OrthancDicomWeb-1.21/Resources/Orthanc/CMake/Compiler.cmake     
2025-08-14 16:38:00.000000000 +0200
+++ new/OrthancDicomWeb-1.22/Resources/Orthanc/CMake/Compiler.cmake     
2025-12-02 17:16:34.000000000 +0100
@@ -21,6 +21,8 @@
 
 
 # This file sets all the compiler-related flags
+message(STATUS "CMAKE_CXX_COMPILER_ID is ${CMAKE_CXX_COMPILER_ID}")
+message(STATUS "CMAKE_SYSTEM_NAME is ${CMAKE_SYSTEM_NAME}")
 
 if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
   # Since Orthanc 1.12.7 that allows CMake 4.0, builds for macOS
@@ -246,6 +248,9 @@
   # fix this error that appears with recent compilers on MacOS: 
boost/mpl/aux_/integral_wrapper.hpp:73:31: error: integer value -1 is outside 
the valid range of values [0, 3] for this enumeration type 
[-Wenum-constexpr-conversion]
   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-enum-constexpr-conversion")
 
+  # it seems that some recent MacOS compilers don't set these flags correctly 
which prevents zlib from building correctly
+  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_LARGEFILE64_SOURCE=1 
-D_FILE_OFFSET_BITS=64")
+
   add_definitions(
     -D_XOPEN_SOURCE=1
     )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/OrthancDicomWeb-1.21/Resources/Orthanc/CMake/DownloadOrthancFramework.cmake 
new/OrthancDicomWeb-1.22/Resources/Orthanc/CMake/DownloadOrthancFramework.cmake
--- 
old/OrthancDicomWeb-1.21/Resources/Orthanc/CMake/DownloadOrthancFramework.cmake 
    2025-08-14 16:38:00.000000000 +0200
+++ 
new/OrthancDicomWeb-1.22/Resources/Orthanc/CMake/DownloadOrthancFramework.cmake 
    2025-12-02 17:16:34.000000000 +0100
@@ -175,6 +175,8 @@
         set(ORTHANC_FRAMEWORK_MD5 "eb1c719234338e8277b80d3453563e9f")
       elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.12.9")
         set(ORTHANC_FRAMEWORK_MD5 "66b5a2ee60706c4a502896083b9e1a01")
+      elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.12.10")
+        set(ORTHANC_FRAMEWORK_MD5 "d5e1ba442104c89a24013cb859a9d6bf")
 
       # Below this point are development snapshots that were used to
       # release some plugin, before an official release of the Orthanc
@@ -207,6 +209,23 @@
         # DICOMweb 1.15 (framework pre-1.12.2)
         set(ORTHANC_FRAMEWORK_PRE_RELEASE ON)
         set(ORTHANC_FRAMEWORK_MD5 "ebe8bdf388319f1c9536b2b680451848")
+      elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "36cd91a53403")
+        # Advanced storage 0.2.0 (framework pre-1.12.10)
+        set(ORTHANC_FRAMEWORK_PRE_RELEASE ON)
+        set(ORTHANC_FRAMEWORK_MD5 "911105f18a154b5e106985d8fcfcb620")
+      elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "9eb77f159b9d")
+        # Advanced storage 0.2.2 (framework pre-1.12.10)
+        set(ORTHANC_FRAMEWORK_PRE_RELEASE ON)
+        set(ORTHANC_FRAMEWORK_MD5 "bd5ba2cec329010b912209345acbdeaf")
+      elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "0ebe8cfd9bf7")
+        # Worklists plugin 0.9.0 (framework pre-1.12.10)
+        set(ORTHANC_FRAMEWORK_PRE_RELEASE ON)
+        set(ORTHANC_FRAMEWORK_MD5 "17a5ca9254e881ab89c93d052d4655cb")
+      elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "e0979326ac53")
+        # DICOMweb 1.22 + PG 10.0 (framework post-1.12.10)
+        # for BlockingSharedMessageQueue + fix SetCurrentThreadName from 
plugins
+        set(ORTHANC_FRAMEWORK_PRE_RELEASE ON)
+        set(ORTHANC_FRAMEWORK_MD5 "e66a7e996d56063b3abb790bb8f12e8d")
       endif()
     endif()
   endif()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/OrthancDicomWeb-1.21/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp 
new/OrthancDicomWeb-1.22/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp
--- 
old/OrthancDicomWeb-1.21/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp  
    2025-08-14 16:38:00.000000000 +0200
+++ 
new/OrthancDicomWeb-1.22/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp  
    2025-12-02 17:16:34.000000000 +0100
@@ -23,6 +23,7 @@
 
 #include "OrthancPluginCppWrapper.h"
 
+#include <cassert>
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/move/unique_ptr.hpp>
 #include <boost/thread.hpp>
@@ -220,6 +221,19 @@
   }
 
 
+  MemoryBuffer::~MemoryBuffer()
+  {
+    try
+    {
+      Clear();
+    }
+    catch (ORTHANC_PLUGINS_EXCEPTION_CLASS&)
+    {
+      // Don't throw exceptions in destructors
+    }
+  }
+
+
   void MemoryBuffer::Clear()
   {
     if (buffer_.data != NULL)
@@ -350,6 +364,38 @@
     }
   }
 
+
+#if (HAS_ORTHANC_PLUGIN_PEERS == 1) || (HAS_ORTHANC_PLUGIN_HTTP_CLIENT == 1) 
|| (HAS_ORTHANC_PLUGIN_GENERIC_CALL_REST_API == 1)
+  static void DecodeHttpHeaders(HttpHeaders& target,
+                                const MemoryBuffer& source)
+  {
+    Json::Value v;
+    source.ToJson(v);
+
+    if (v.type() != Json::objectValue)
+    {
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
+    }
+
+    Json::Value::Members members = v.getMemberNames();
+    target.clear();
+
+    for (size_t i = 0; i < members.size(); i++)
+    {
+      const Json::Value& h = v[members[i]];
+      if (h.type() != Json::stringValue)
+      {
+        ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
+      }
+      else
+      {
+        target[members[i]] = h.asString();
+      }
+    }
+  }
+#endif
+
+
   // helper class to convert std::map of headers to the plugin SDK C structure
   class PluginHttpHeaders
   {
@@ -623,6 +669,19 @@
   }
 
 
+  OrthancString::~OrthancString()
+  {
+    try
+    {
+      Clear();
+    }
+    catch (ORTHANC_PLUGINS_EXCEPTION_CLASS&)
+    {
+      // Don't throw exceptions in destructors
+    }
+  }
+
+
   void OrthancString::Assign(char* str)
   {
     Clear();
@@ -1272,6 +1331,20 @@
     }
   }
 
+
+  OrthancImage::~OrthancImage()
+  {
+    try
+    {
+      Clear();
+    }
+    catch (ORTHANC_PLUGINS_EXCEPTION_CLASS&)
+    {
+      // Don't throw exceptions in destructors
+    }
+  }
+
+
   void OrthancImage::UncompressPngImage(const void* data,
                                         size_t size)
   {
@@ -2083,8 +2156,30 @@
                             unsigned int timeout) const
   {
     MemoryBuffer buffer;
+    HttpHeaders answerHeaders;
+
+    if (DoPost(buffer, answerHeaders, index, uri, body, headers, timeout))
+    {
+      buffer.ToJson(target);
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  bool OrthancPeers::DoPost(Json::Value& target,
+                            HttpHeaders& answerHeaders,
+                            size_t index,
+                            const std::string& uri,
+                            const std::string& body,
+                            const HttpHeaders& headers, 
+                            unsigned int timeout) const
+  {
+    MemoryBuffer buffer;
 
-    if (DoPost(buffer, index, uri, body, headers, timeout))
+    if (DoPost(buffer, answerHeaders, index, uri, body, headers, timeout))
     {
       buffer.ToJson(target);
       return true;
@@ -2142,11 +2237,23 @@
                             const std::string& body,
                             const HttpHeaders& headers) const
   {
-    return DoPost(target, index, uri, body, headers, timeout_);
+    HttpHeaders answerHeaders;
+    return DoPost(target, answerHeaders, index, uri, body, headers, timeout_);
   }
 
+  bool OrthancPeers::DoPost(MemoryBuffer& target,
+                            size_t index,
+                            const std::string& uri,
+                            const std::string& body,
+                            const HttpHeaders& headers,
+                            unsigned int timeout) const
+  {
+    HttpHeaders answerHeaders;
+    return DoPost(target, answerHeaders, index, uri, body, headers, timeout);
+  }
 
   bool OrthancPeers::DoPost(MemoryBuffer& target,
+                            HttpHeaders& answerHeaders,
                             size_t index,
                             const std::string& uri,
                             const std::string& body,
@@ -2165,17 +2272,20 @@
     }
 
     OrthancPlugins::MemoryBuffer answer;
+    OrthancPlugins::MemoryBuffer answerHeadersBuffer;
     uint16_t status;
     PluginHttpHeaders pluginHeaders(headers);
 
     OrthancPluginErrorCode code = OrthancPluginCallPeerApi
-      (GetGlobalContext(), *answer, NULL, &status, peers_,
+      (GetGlobalContext(), *answer, *answerHeadersBuffer, &status, peers_,
        static_cast<uint32_t>(index), OrthancPluginHttpMethod_Post, uri.c_str(),
        pluginHeaders.GetSize(), pluginHeaders.GetKeys(), 
pluginHeaders.GetValues(), body.empty() ? NULL : body.c_str(), body.size(), 
timeout);
 
     if (code == OrthancPluginErrorCode_Success)
     {
       target.Swap(answer);
+      DecodeHttpHeaders(answerHeaders, answerHeadersBuffer);
+      
       return (status == 200);
     }
     else
@@ -2610,33 +2720,43 @@
 
         return;
       }
-      else if (state == "Running")
+      else if (state == "Running" ||
+               state == "Pending" ||
+               state == "Paused" ||
+               state == "Retry")
       {
         continue;
       }
-      else if (!status.isMember("ErrorCode") ||
-               status["ErrorCode"].type() != Json::intValue)
+      else if (state == "Failure")
       {
-        
ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_InternalError);
-      }
-      else
-      {
-        if (!status.isMember("ErrorDescription") ||
-            status["ErrorDescription"].type() != Json::stringValue)
+        if (!status.isMember("ErrorCode") ||
+            status["ErrorCode"].type() != Json::intValue)
         {
-          ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(status["ErrorCode"].asInt());
+          
ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_InternalError);
         }
         else
         {
-#if HAS_ORTHANC_EXCEPTION == 1
-          throw 
Orthanc::OrthancException(static_cast<Orthanc::ErrorCode>(status["ErrorCode"].asInt()),
-                                          
status["ErrorDescription"].asString());
-#else
-          ORTHANC_PLUGINS_LOG_ERROR("Exception while executing the job: " + 
status["ErrorDescription"].asString());
-          
ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(status["ErrorCode"].asInt());          
-#endif
+          if (!status.isMember("ErrorDescription") ||
+              status["ErrorDescription"].type() != Json::stringValue)
+          {
+            
ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(status["ErrorCode"].asInt());
+          }
+          else
+          {
+  #if HAS_ORTHANC_EXCEPTION == 1
+            throw 
Orthanc::OrthancException(static_cast<Orthanc::ErrorCode>(status["ErrorCode"].asInt()),
+                                            
status["ErrorDescription"].asString());
+  #else
+            ORTHANC_PLUGINS_LOG_ERROR("Exception while executing the job: " + 
status["ErrorDescription"].asString());
+            
ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(status["ErrorCode"].asInt());          
+  #endif
+          }
         }
       }
+      else
+      {
+        
ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_InternalError);
+      }
     }
   }
 
@@ -3222,36 +3342,6 @@
   }
 #endif    
 
-
-  static void DecodeHttpHeaders(HttpHeaders& target,
-                                const MemoryBuffer& source)
-  {
-    Json::Value v;
-    source.ToJson(v);
-
-    if (v.type() != Json::objectValue)
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
-    }
-
-    Json::Value::Members members = v.getMemberNames();
-    target.clear();
-
-    for (size_t i = 0; i < members.size(); i++)
-    {
-      const Json::Value& h = v[members[i]];
-      if (h.type() != Json::stringValue)
-      {
-        ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
-      }
-      else
-      {
-        target[members[i]] = h.asString();
-      }
-    }
-  }
-
-
   void HttpClient::ExecuteWithoutStream(uint16_t& httpStatus,
                                         HttpHeaders& answerHeaders,
                                         std::string& answerBody,
@@ -4571,8 +4661,11 @@
     uint8_t found = false;
     OrthancPlugins::MemoryBuffer valueBuffer;
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     OrthancPluginErrorCode code = 
OrthancPluginDequeueValue(OrthancPlugins::GetGlobalContext(), &found,
                                                             *valueBuffer, 
queueId_.c_str(), origin);
+#pragma GCC diagnostic pop
 
     if (code != OrthancPluginErrorCode_Success)
     {
@@ -4607,4 +4700,54 @@
     }
   }
 #endif
+
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+  bool Queue::ReserveInternal(std::string& value, uint64_t& valueId, 
OrthancPluginQueueOrigin origin, uint32_t releaseTimeout)
+  {
+    uint8_t found = false;
+    OrthancPlugins::MemoryBuffer valueBuffer;
+
+    OrthancPluginErrorCode code = 
OrthancPluginReserveQueueValue(OrthancPlugins::GetGlobalContext(), &found,
+                                                                 *valueBuffer, 
&valueId, queueId_.c_str(), origin, releaseTimeout);
+
+    if (code != OrthancPluginErrorCode_Success)
+    {
+      ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code);
+    }
+    else if (found)
+    {
+      valueBuffer.ToString(value);
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+#endif
+
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+  bool Queue::ReserveBack(std::string& value, uint64_t& valueId, uint32_t 
releaseTimeout)
+  {
+    return ReserveInternal(value, valueId, OrthancPluginQueueOrigin_Back, 
releaseTimeout);
+  }
+#endif
+
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+  bool Queue::ReserveFront(std::string& value, uint64_t& valueId, uint32_t 
releaseTimeout)
+  {
+    return ReserveInternal(value, valueId, OrthancPluginQueueOrigin_Front, 
releaseTimeout);
+  }
+#endif
+
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+  void Queue::Acknowledge(uint64_t valueId)
+  {
+    OrthancPluginAcknowledgeQueueValue(OrthancPlugins::GetGlobalContext(), 
queueId_.c_str(), valueId);
+  }
+#endif
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/OrthancDicomWeb-1.21/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h 
new/OrthancDicomWeb-1.22/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h
--- 
old/OrthancDicomWeb-1.21/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h    
    2025-08-14 16:38:00.000000000 +0200
+++ 
new/OrthancDicomWeb-1.22/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h    
    2025-12-02 17:16:34.000000000 +0100
@@ -142,6 +142,12 @@
 #  define HAS_ORTHANC_PLUGIN_QUEUES            0
 #endif
 
+#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 10)
+#  define HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE   1
+#else
+#  define HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE   0
+#endif
+
 
 // Macro to tag a function as having been deprecated
 #if (__cplusplus >= 201402L)  // C++14
@@ -213,10 +219,7 @@
   public:
     MemoryBuffer();
 
-    ~MemoryBuffer()
-    {
-      Clear();
-    }
+    ~MemoryBuffer();
 
     OrthancPluginMemoryBuffer* operator*()
     {
@@ -371,10 +374,7 @@
     {
     }
 
-    ~OrthancString()
-    {
-      Clear();
-    }
+    ~OrthancString();
 
     // This transfers ownership, warning: The string must have been
     // allocated by the Orthanc core
@@ -491,10 +491,7 @@
                  uint32_t                  pitch,
                  void*                     buffer);
 
-    ~OrthancImage()
-    {
-      Clear();
-    }
+    ~OrthancImage();
 
     void UncompressPngImage(const void* data,
                             size_t size);
@@ -879,6 +876,14 @@
                 unsigned int timeout) const;
 
     bool DoPost(MemoryBuffer& target,
+                HttpHeaders& answerHeaders,
+                size_t index,
+                const std::string& uri,
+                const std::string& body,
+                const HttpHeaders& headers,
+                unsigned int timeout) const;
+
+    bool DoPost(MemoryBuffer& target,
                 const std::string& name,
                 const std::string& uri,
                 const std::string& body,
@@ -896,6 +901,14 @@
                 const std::string& body,
                 const HttpHeaders& headers,
                 unsigned int timeout) const;
+    
+    bool DoPost(Json::Value& target,
+                HttpHeaders& answerHeaders,
+                size_t index,
+                const std::string& uri,
+                const std::string& body,
+                const HttpHeaders& headers,
+                unsigned int timeout) const;
 
     bool DoPost(Json::Value& target,
                 const std::string& name,
@@ -1710,6 +1723,10 @@
 
     bool DequeueInternal(std::string& value, OrthancPluginQueueOrigin origin);
 
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+    bool ReserveInternal(std::string& value, uint64_t& valueId, 
OrthancPluginQueueOrigin origin, uint32_t releaseTimeout);
+#endif
+
   public:
     explicit Queue(const std::string& queueId) :
       queueId_(queueId)
@@ -1729,17 +1746,37 @@
       Enqueue(value.empty() ? NULL : value.c_str(), value.size());
     }
 
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+    // Use ReserveBack() instead
+    ORTHANC_PLUGIN_DEPRECATED
+#endif
     bool DequeueBack(std::string& value)
     {
       return DequeueInternal(value, OrthancPluginQueueOrigin_Back);
     }
 
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+    // Use ReserveFront() instead
+    ORTHANC_PLUGIN_DEPRECATED
+#endif
     bool DequeueFront(std::string& value)
     {
       return DequeueInternal(value, OrthancPluginQueueOrigin_Front);
     }
 
     uint64_t GetSize();
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+    bool ReserveBack(std::string& value, uint64_t& valueId, uint32_t 
releaseTimeout);
+#endif
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+    bool ReserveFront(std::string& value, uint64_t& valueId, uint32_t 
releaseTimeout);
+#endif
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+    void Acknowledge(uint64_t valueId);
+#endif
   };
 #endif
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/OrthancDicomWeb-1.21/Resources/SyncOrthancFolder.py 
new/OrthancDicomWeb-1.22/Resources/SyncOrthancFolder.py
--- old/OrthancDicomWeb-1.21/Resources/SyncOrthancFolder.py     2025-08-14 
16:38:00.000000000 +0200
+++ new/OrthancDicomWeb-1.22/Resources/SyncOrthancFolder.py     2025-12-02 
17:16:34.000000000 +0100
@@ -19,8 +19,8 @@
     ('OrthancFramework/Resources/CMake/Compiler.cmake', 'CMake'),
     ('OrthancFramework/Resources/CMake/DownloadOrthancFramework.cmake', 
'CMake'),
     ('OrthancFramework/Resources/CMake/DownloadPackage.cmake', 'CMake'),
+    ('OrthancFramework/Resources/CMake/EmbedResources.py', 'CMake'),
     ('OrthancFramework/Resources/CMake/GoogleTestConfiguration.cmake', 
'CMake'),
-    ('OrthancFramework/Resources/EmbedResources.py', 'CMake'),
     ('OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake', 
'Toolchains'),
     ('OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain32.cmake', 
'Toolchains'),
     ('OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain64.cmake', 
'Toolchains'),


++++++ framework2.diff ++++++
--- a/Plugin/WadoRs.cpp Tue Dec 02 17:17:12 2025 +0100
+++ b/Plugin/WadoRs.cpp Tue Dec 09 07:57:08 2025 +0100
@@ -32,9 +32,12 @@
 #include <Toolbox.h>
 #include <SerializationToolbox.h>
 #include <MultiThreading/SharedMessageQueue.h>
-#include <MultiThreading/BlockingSharedMessageQueue.h>
 #include <Compression/GzipCompressor.h>
 
+#if ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 12, 11)
+#  include <MultiThreading/BlockingSharedMessageQueue.h>
+#endif
+
 #include <memory>
 #include <boost/thread/mutex.hpp>
 #include <boost/thread.hpp>
@@ -445,11 +448,16 @@
 
 class ThreadedInstanceLoader : public InstanceLoader
 {
+private:
   std::vector<boost::thread*>         threads_;
 
   Orthanc::SharedMessageQueue         instancesToPreload_;
 
+#if ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 12, 11)
   Orthanc::BlockingSharedMessageQueue loadedInstances_;
+#else
+  Orthanc::SharedMessageQueue         loadedInstances_;
+#endif
 
   bool                                loadersShouldStop_;
 
@@ -457,7 +465,11 @@
   ThreadedInstanceLoader(size_t threadCount, bool transcode, 
Orthanc::DicomTransferSyntax transferSyntax)
   : InstanceLoader(transcode, transferSyntax),
     instancesToPreload_(0),
-    loadedInstances_(3*threadCount), // to limit the number of loaded 
instances in memory
+#if ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 12, 11)
+    loadedInstances_(3 * threadCount), // to limit the number of loaded 
instances in memory
+#else
+    loadedInstances_(0),  // don't limit the number of loaded instances, 
otherwise extra instances would be lost
+#endif
     loadersShouldStop_(false)
   {
     for (size_t i = 0; i < threadCount; i++)

Reply via email to