changeset 232:4e15eace9b90

reorganization in DatabaseBackendAdapterV3
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 06 Apr 2021 12:50:06 +0200
parents 0a9b48d19643
children 7d46c99523a2
files Framework/Plugins/DatabaseBackendAdapterV3.cpp Framework/Plugins/IDatabaseBackendOutput.h Framework/Plugins/IndexBackend.cpp Framework/Plugins/IndexBackend.h
diffstat 4 files changed, 70 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Plugins/DatabaseBackendAdapterV3.cpp	Tue Apr 06 11:59:31 2021 +0200
+++ b/Framework/Plugins/DatabaseBackendAdapterV3.cpp	Tue Apr 06 12:50:06 2021 +0200
@@ -61,10 +61,23 @@
   class DatabaseBackendAdapterV3::Adapter : public boost::noncopyable
   {
   private:
-    std::unique_ptr<IndexBackend>  backend_;
+    std::unique_ptr<IndexBackend>      backend_;
+    OrthancPluginContext*              context_;
     boost::mutex                       managerMutex_;
     std::unique_ptr<DatabaseManager>   manager_;
 
+    DatabaseManager& GetManager() const
+    {
+      if (manager_.get() == NULL)
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
+      }
+      else
+      {
+        return *manager_;
+      }
+    }    
+
   public:
     Adapter(IndexBackend* backend) :
       backend_(backend)
@@ -73,11 +86,28 @@
       {
         throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
       }
+      else
+      {
+        context_ = backend_->GetContext();
+      }
+    }
+
+    OrthancPluginContext* GetContext() const
+    {
+      return context_;
     }
 
-    IndexBackend& GetBackend() const
+    uint32_t GetDatabaseVersion()
     {
-      return *backend_;
+      boost::mutex::scoped_lock lock(managerMutex_);
+      return backend_->GetDatabaseVersion(GetManager());
+    }
+
+    void UpgradeDatabase(OrthancPluginStorageArea* storageArea,
+                         uint32_t targetVersion)
+    {
+      boost::mutex::scoped_lock lock(managerMutex_);
+      backend_->UpgradeDatabase(GetManager(), targetVersion, storageArea);
     }
 
     void OpenConnection()
@@ -113,23 +143,25 @@
     {
     private:
       boost::mutex::scoped_lock  lock_;
-      DatabaseManager*           manager_;
+      IndexBackend&              backend_;
+      DatabaseManager&           manager_;
       
     public:
       DatabaseAccessor(Adapter& adapter) :
         lock_(adapter.managerMutex_),
-        manager_(adapter.manager_.get())
+        backend_(*adapter.backend_),
+        manager_(adapter.GetManager())
       {
-        if (manager_ == NULL)
-        {
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-        }
+      }
+
+      IndexBackend& GetBackend() const
+      {
+        return backend_;
       }
 
       DatabaseManager& GetManager() const
       {
-        assert(manager_ != NULL);
-        return *manager_;
+        return manager_;
       }
     };
   };
@@ -698,7 +730,7 @@
     Adapter&   adapter_;
     std::unique_ptr<Adapter::DatabaseAccessor>  accessor_;
     std::unique_ptr<Output>    output_;
-
+    
   public:
     Transaction(Adapter& adapter) :
       adapter_(adapter),
@@ -713,7 +745,7 @@
 
     IndexBackend& GetBackend() const
     {
-      return adapter_.GetBackend();
+      return accessor_->GetBackend();
     }
 
     Output& GetOutput() const
@@ -861,7 +893,7 @@
       adapter->OpenConnection();
       return OrthancPluginErrorCode_Success;
     }
-    ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetBackend().GetContext());
+    ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetContext());
   }
 
   
@@ -874,7 +906,7 @@
       adapter->CloseConnection();
       return OrthancPluginErrorCode_Success;
     }
-    ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetBackend().GetContext());
+    ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetContext());
   }
 
   
@@ -894,7 +926,7 @@
       }
       else
       {
-        OrthancPluginLogError(adapter->GetBackend().GetContext(), "More than one index backend was registered, internal error");
+        OrthancPluginLogError(adapter->GetContext(), "More than one index backend was registered, internal error");
       }
       
       delete adapter;
@@ -911,11 +943,10 @@
       
     try
     {
-      DatabaseBackendAdapterV3::Adapter::DatabaseAccessor accessor(*adapter);
-      *version = adapter->GetBackend().GetDatabaseVersion(accessor.GetManager());
+      *version = adapter->GetDatabaseVersion();
       return OrthancPluginErrorCode_Success;
     }
-    ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetBackend().GetContext());
+    ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetContext());
   }
 
 
@@ -927,11 +958,10 @@
       
     try
     {
-      DatabaseBackendAdapterV3::Adapter::DatabaseAccessor accessor(*adapter);
-      adapter->GetBackend().UpgradeDatabase(accessor.GetManager(), targetVersion, storageArea);
+      adapter->UpgradeDatabase(storageArea, targetVersion);
       return OrthancPluginErrorCode_Success;
     }
-    ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetBackend().GetContext());
+    ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetContext());
   }
 
 
@@ -963,7 +993,7 @@
       
       return OrthancPluginErrorCode_Success;
     }
-    ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetBackend().GetContext());
+    ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetContext());
   }
 
   
--- a/Framework/Plugins/IDatabaseBackendOutput.h	Tue Apr 06 11:59:31 2021 +0200
+++ b/Framework/Plugins/IDatabaseBackendOutput.h	Tue Apr 06 12:50:06 2021 +0200
@@ -28,6 +28,12 @@
   class IDatabaseBackendOutput : public boost::noncopyable
   {
   public:
+    /**
+     * Contrarily to its parent "IDatabaseBackendOutput" class, the
+     * "IFactory" subclass *can* be invoked from multiple threads if
+     * used through "DatabaseBackendAdapterV3". Make sure to implement
+     * proper locking if need be.
+     **/
     class IFactory : public boost::noncopyable
     {
     public:
--- a/Framework/Plugins/IndexBackend.cpp	Tue Apr 06 11:59:31 2021 +0200
+++ b/Framework/Plugins/IndexBackend.cpp	Tue Apr 06 12:50:06 2021 +0200
@@ -318,6 +318,8 @@
 
   void IndexBackend::SetOutputFactory(IDatabaseBackendOutput::IFactory* factory)
   {
+    boost::unique_lock<boost::shared_mutex> lock(outputFactoryMutex_);
+      
     if (factory == NULL)
     {
       throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
@@ -335,6 +337,8 @@
 
   IDatabaseBackendOutput* IndexBackend::CreateOutput()
   {
+    boost::shared_lock<boost::shared_mutex> lock(outputFactoryMutex_);
+      
     if (outputFactory_.get() == NULL)
     {
       throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
--- a/Framework/Plugins/IndexBackend.h	Tue Apr 06 11:59:31 2021 +0200
+++ b/Framework/Plugins/IndexBackend.h	Tue Apr 06 12:50:06 2021 +0200
@@ -25,9 +25,15 @@
 
 #include <OrthancException.h>
 
+#include <boost/thread/shared_mutex.hpp>
+
 
 namespace OrthancDatabases
 {
+  /**
+   * WARNING: This class can be invoked concurrently by several
+   * threads if it is used from "DatabaseBackendAdapterV3".
+   **/
   class IndexBackend : public IDatabaseBackend
   {
   private:
@@ -35,6 +41,7 @@
 
     OrthancPluginContext*  context_;
 
+    boost::shared_mutex                                outputFactoryMutex_;
     std::unique_ptr<IDatabaseBackendOutput::IFactory>  outputFactory_;
     
   protected: