changeset 5398:08b5516c6e5e

compatibility of OrthancFramework with latest releases of Emscripten
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 11 Oct 2023 15:26:45 +0200
parents e7f6ec8cbc35
children b7e60d081b81 1c6708a0e0c6
files OrthancFramework/Resources/CMake/BoostConfiguration.cmake OrthancFramework/Resources/Patches/boost-1.83.0-emscripten.patch OrthancFramework/Sources/Enumerations.cpp OrthancFramework/Sources/FileStorage/MemoryStorageArea.cpp OrthancFramework/Sources/FileStorage/MemoryStorageArea.h OrthancFramework/Sources/MultiThreading/Mutex.h
diffstat 6 files changed, 227 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancFramework/Resources/CMake/BoostConfiguration.cmake	Wed Oct 11 14:47:39 2023 +0200
+++ b/OrthancFramework/Resources/CMake/BoostConfiguration.cmake	Wed Oct 11 15:26:45 2023 +0200
@@ -107,6 +107,25 @@
 
 
   ##
+  ## Apply the patches to remove threads from boost::locale (required
+  ## since around Emscripten 3.x)
+  ##
+
+  if (FirstRun)
+    execute_process(
+      COMMAND ${PATCH_EXECUTABLE} -p0 -N -i
+      ${CMAKE_CURRENT_LIST_DIR}/../Patches/boost-1.83.0-emscripten.patch
+      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+      RESULT_VARIABLE Failure
+      )
+
+    if (Failure)
+      message(FATAL_ERROR "Error while patching a file")
+    endif()
+  endif()
+
+
+  ##
   ## Generic configuration of Boost
   ## 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Resources/Patches/boost-1.83.0-emscripten.patch	Wed Oct 11 15:26:45 2023 +0200
@@ -0,0 +1,125 @@
+diff -urEb boost_1_83_0.orig/libs/locale/src/boost/locale/shared/date_time.cpp boost_1_83_0/libs/locale/src/boost/locale/shared/date_time.cpp
+--- boost_1_83_0.orig/libs/locale/src/boost/locale/shared/date_time.cpp	2023-10-11 14:35:14.000000000 +0200
++++ boost_1_83_0/libs/locale/src/boost/locale/shared/date_time.cpp	2023-10-11 15:10:23.949459131 +0200
+@@ -7,8 +7,10 @@
+ #include <boost/locale/date_time.hpp>
+ #include <boost/locale/formatting.hpp>
+ #include <boost/core/exchange.hpp>
+-#include <boost/thread/locks.hpp>
+-#include <boost/thread/mutex.hpp>
++#if !defined(__EMSCRIPTEN__)
++#  include <boost/thread/locks.hpp>
++#  include <boost/thread/mutex.hpp>
++#endif
+ #include <cmath>
+ 
+ namespace boost { namespace locale {
+@@ -394,6 +396,7 @@
+         return impl_->get_option(abstract_calendar::is_dst) != 0;
+     }
+ 
++#if !defined(__EMSCRIPTEN__)
+     namespace time_zone {
+         boost::mutex& tz_mutex()
+         {
+@@ -416,5 +419,6 @@
+             return boost::exchange(tz_id(), new_id);
+         }
+     } // namespace time_zone
++#endif
+ 
+ }} // namespace boost::locale
+diff -urEb boost_1_83_0.orig/libs/locale/src/boost/locale/shared/generator.cpp boost_1_83_0/libs/locale/src/boost/locale/shared/generator.cpp
+--- boost_1_83_0.orig/libs/locale/src/boost/locale/shared/generator.cpp	2023-10-11 14:35:14.000000000 +0200
++++ boost_1_83_0/libs/locale/src/boost/locale/shared/generator.cpp	2023-10-11 15:10:01.301651695 +0200
+@@ -7,8 +7,11 @@
+ #include <boost/locale/encoding.hpp>
+ #include <boost/locale/generator.hpp>
+ #include <boost/locale/localization_backend.hpp>
+-#include <boost/thread/locks.hpp>
+-#include <boost/thread/mutex.hpp>
++
++#if !defined(__EMSCRIPTEN__)
++#  include <boost/thread/locks.hpp>
++#  include <boost/thread/mutex.hpp>
++#endif
+ #include <algorithm>
+ #include <map>
+ #include <vector>
+@@ -21,7 +24,9 @@
+         {}
+ 
+         mutable std::map<std::string, std::locale> cached;
++#if !defined(__EMSCRIPTEN__)
+         mutable boost::mutex cached_lock;
++#endif
+ 
+         category_t cats;
+         char_facet_t chars;
+@@ -101,7 +106,9 @@
+     std::locale generator::generate(const std::locale& base, const std::string& id) const
+     {
+         if(d->caching_enabled) {
++#if !defined(__EMSCRIPTEN__)
+             boost::unique_lock<boost::mutex> guard(d->cached_lock);
++#endif
+             const auto p = d->cached.find(id);
+             if(p != d->cached.end())
+                 return p->second;
+@@ -126,7 +133,9 @@
+                 result = backend->install(result, facet, char_facet_t::nochar);
+         }
+         if(d->caching_enabled) {
++#if !defined(__EMSCRIPTEN__)
+             boost::unique_lock<boost::mutex> guard(d->cached_lock);
++#endif
+             const auto p = d->cached.find(id);
+             if(p == d->cached.end())
+                 d->cached[id] = result;
+diff -urEb boost_1_83_0.orig/libs/locale/src/boost/locale/shared/localization_backend.cpp boost_1_83_0/libs/locale/src/boost/locale/shared/localization_backend.cpp
+--- boost_1_83_0.orig/libs/locale/src/boost/locale/shared/localization_backend.cpp	2023-10-11 14:35:14.000000000 +0200
++++ boost_1_83_0/libs/locale/src/boost/locale/shared/localization_backend.cpp	2023-10-11 15:11:11.549053453 +0200
+@@ -5,8 +5,10 @@
+ // https://www.boost.org/LICENSE_1_0.txt
+ 
+ #include <boost/locale/localization_backend.hpp>
+-#include <boost/thread/locks.hpp>
+-#include <boost/thread/mutex.hpp>
++#if !defined(__EMSCRIPTEN__)
++#  include <boost/thread/locks.hpp>
++#  include <boost/thread/mutex.hpp>
++#endif
+ #include <functional>
+ #include <memory>
+ #include <vector>
+@@ -211,11 +213,13 @@
+             return mgr;
+         }
+ 
++#if !defined(__EMSCRIPTEN__)
+         boost::mutex& localization_backend_manager_mutex()
+         {
+             static boost::mutex the_mutex;
+             return the_mutex;
+         }
++#endif
+         localization_backend_manager& localization_backend_manager_global()
+         {
+             static localization_backend_manager the_manager = make_default_backend_mgr();
+@@ -225,12 +229,16 @@
+ 
+     localization_backend_manager localization_backend_manager::global()
+     {
++#if !defined(__EMSCRIPTEN__)
+         boost::unique_lock<boost::mutex> lock(localization_backend_manager_mutex());
++#endif
+         return localization_backend_manager_global();
+     }
+     localization_backend_manager localization_backend_manager::global(const localization_backend_manager& in)
+     {
++#if !defined(__EMSCRIPTEN__)
+         boost::unique_lock<boost::mutex> lock(localization_backend_manager_mutex());
++#endif
+         return exchange(localization_backend_manager_global(), in);
+     }
+ 
--- a/OrthancFramework/Sources/Enumerations.cpp	Wed Oct 11 14:47:39 2023 +0200
+++ b/OrthancFramework/Sources/Enumerations.cpp	Wed Oct 11 15:26:45 2023 +0200
@@ -24,11 +24,11 @@
 #include "PrecompiledHeaders.h"
 #include "Enumerations.h"
 
+#include "Logging.h"
+#include "MultiThreading/Mutex.h"
 #include "OrthancException.h"
 #include "Toolbox.h"
-#include "Logging.h"
-
-#include <boost/thread/mutex.hpp>
+
 #include <string.h>
 #include <cassert>
 #include <boost/algorithm/string/replace.hpp>
@@ -2377,12 +2377,12 @@
   }  
 
 
-  static boost::mutex  defaultEncodingMutex_;  // Should not be necessary
-  static Encoding      defaultEncoding_ = ORTHANC_DEFAULT_DICOM_ENCODING;
+  static Mutex     defaultEncodingMutex_;  // Should not be necessary
+  static Encoding  defaultEncoding_ = ORTHANC_DEFAULT_DICOM_ENCODING;
   
   Encoding GetDefaultDicomEncoding()
   {
-    boost::mutex::scoped_lock lock(defaultEncodingMutex_);
+    Mutex::ScopedLock lock(defaultEncodingMutex_);
     return defaultEncoding_;
   }
 
@@ -2391,7 +2391,7 @@
     std::string name = EnumerationToString(encoding);
     
     {
-      boost::mutex::scoped_lock lock(defaultEncodingMutex_);
+      Mutex::ScopedLock lock(defaultEncodingMutex_);
       defaultEncoding_ = encoding;
     }
 
--- a/OrthancFramework/Sources/FileStorage/MemoryStorageArea.cpp	Wed Oct 11 14:47:39 2023 +0200
+++ b/OrthancFramework/Sources/FileStorage/MemoryStorageArea.cpp	Wed Oct 11 15:26:45 2023 +0200
@@ -49,7 +49,7 @@
     LOG(INFO) << "Creating attachment \"" << uuid << "\" of \"" << static_cast<int>(type)
               << "\" type (size: " << (size / (1024 * 1024) + 1) << "MB)";
 
-    boost::mutex::scoped_lock lock(mutex_);
+    Mutex::ScopedLock lock(mutex_);
 
     if (size != 0 &&
         content == NULL)
@@ -73,7 +73,7 @@
     LOG(INFO) << "Reading attachment \"" << uuid << "\" of \""
               << static_cast<int>(type) << "\" content type";
 
-    boost::mutex::scoped_lock lock(mutex_);
+    Mutex::ScopedLock lock(mutex_);
 
     Content::const_iterator found = content_.find(uuid);
 
@@ -111,7 +111,7 @@
     }
     else
     {
-      boost::mutex::scoped_lock lock(mutex_);
+      Mutex::ScopedLock lock(mutex_);
 
       Content::const_iterator found = content_.find(uuid);
 
@@ -152,7 +152,7 @@
   {
     LOG(INFO) << "Deleting attachment \"" << uuid << "\" of type " << static_cast<int>(type);
 
-    boost::mutex::scoped_lock lock(mutex_);
+    Mutex::ScopedLock lock(mutex_);
 
     Content::iterator found = content_.find(uuid);
     
--- a/OrthancFramework/Sources/FileStorage/MemoryStorageArea.h	Wed Oct 11 14:47:39 2023 +0200
+++ b/OrthancFramework/Sources/FileStorage/MemoryStorageArea.h	Wed Oct 11 15:26:45 2023 +0200
@@ -26,8 +26,8 @@
 #include "IStorageArea.h"
 
 #include "../Compatibility.h"  // For ORTHANC_OVERRIDE
+#include "../MultiThreading/Mutex.h"
 
-#include <boost/thread/mutex.hpp>
 #include <map>
 
 namespace Orthanc
@@ -37,8 +37,8 @@
   private:
     typedef std::map<std::string, std::string*>  Content;
     
-    boost::mutex  mutex_;
-    Content       content_;
+    Mutex    mutex_;
+    Content  content_;
     
   public:
     virtual ~MemoryStorageArea();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Sources/MultiThreading/Mutex.h	Wed Oct 11 15:26:45 2023 +0200
@@ -0,0 +1,69 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2021-2023 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#if !defined(__EMSCRIPTEN__)
+#  include <boost/thread/mutex.hpp>
+#endif
+
+namespace Orthanc
+{
+  // Wrapper class for compatibility with Emscripten
+
+#if defined(__EMSCRIPTEN__)
+
+  class ORTHANC_PUBLIC Mutex : public boost::noncopyable
+  {
+  public:
+    class ORTHANC_PUBLIC ScopedLock : public boost::noncopyable
+    {
+    public:
+      explicit ScopedLock(Mutex& mutex)
+      {
+      }
+    };
+  };
+
+#else
+
+  class ORTHANC_PUBLIC Mutex : public boost::noncopyable
+  {
+  private:
+    boost::mutex mutex_;
+
+  public:
+    class ORTHANC_PUBLIC ScopedLock : public boost::noncopyable
+    {
+    private:
+      boost::mutex::scoped_lock lock_;
+
+    public:
+      explicit ScopedLock(Mutex& mutex) :
+        lock_(mutex.mutex_)
+      {
+      }
+    };
+  };
+#endif
+}