changeset 1675:131136aeeaa7 db-changes

improved exception handling in the main program
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 02 Oct 2015 13:57:54 +0200
parents 4fc502d469f4
children f079f3efe33b
files OrthancServer/DicomProtocol/DicomServer.cpp OrthancServer/DicomProtocol/DicomServer.h OrthancServer/main.cpp
diffstat 3 files changed, 83 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/DicomProtocol/DicomServer.cpp	Fri Oct 02 13:31:39 2015 +0200
+++ b/OrthancServer/DicomProtocol/DicomServer.cpp	Fri Oct 02 13:57:54 2015 +0200
@@ -58,56 +58,52 @@
   };
 
 
-  void DicomServer::ServerThread(DicomServer* server)
+  void DicomServer::ServerThread(DicomServer* server,
+                                 T_ASC_Network *network)
   {
-    /* initialize network, i.e. create an instance of T_ASC_Network*. */
-    T_ASC_Network *net;
-    OFCondition cond = ASC_initializeNetwork
-      (NET_ACCEPTOR, OFstatic_cast(int, server->port_), /*opt_acse_timeout*/ 30, &net);
-    if (cond.bad())
-    {
-      LOG(ERROR) << "cannot create network: " << cond.text();
-      throw OrthancException(ErrorCode_DicomPortInUse);
-    }
+      LOG(INFO) << "DICOM server started";
 
-    LOG(INFO) << "DICOM server started";
-
-    server->started_ = true;
+      while (server->continue_)
+      {
+        /* receive an association and acknowledge or reject it. If the association was */
+        /* acknowledged, offer corresponding services and invoke one or more if required. */
+        std::auto_ptr<Internals::CommandDispatcher> dispatcher(Internals::AcceptAssociation(*server, network));
 
-    while (server->continue_)
-    {
-      /* receive an association and acknowledge or reject it. If the association was */
-      /* acknowledged, offer corresponding services and invoke one or more if required. */
-      std::auto_ptr<Internals::CommandDispatcher> dispatcher(Internals::AcceptAssociation(*server, net));
-
-      if (dispatcher.get() != NULL)
-      {
-        if (server->isThreaded_)
+        try
         {
-          server->bagOfDispatchers_.Add(dispatcher.release());
+          if (dispatcher.get() != NULL)
+          {
+            if (server->isThreaded_)
+            {
+              server->bagOfDispatchers_.Add(dispatcher.release());
+            }
+            else
+            {
+              IRunnableBySteps::RunUntilDone(*dispatcher);
+            }
+          }
         }
-        else
+        catch (OrthancException& e)
         {
-          IRunnableBySteps::RunUntilDone(*dispatcher);
+          LOG(ERROR) << "Exception in the DICOM server thread: " << e.What();
         }
       }
-    }
 
-    LOG(INFO) << "DICOM server stopping";
+      LOG(INFO) << "DICOM server stopping";
 
-    if (server->isThreaded_)
-    {
-      server->bagOfDispatchers_.StopAll();
-    }
+      if (server->isThreaded_)
+      {
+        server->bagOfDispatchers_.StopAll();
+      }
 
-    /* drop the network, i.e. free memory of T_ASC_Network* structure. This call */
-    /* is the counterpart of ASC_initializeNetwork(...) which was called above. */
-    cond = ASC_dropNetwork(&net);
-    if (cond.bad())
-    {
-      LOG(ERROR) << "Error while dropping the network: " << cond.text();
-    }
-  }                           
+      /* drop the network, i.e. free memory of T_ASC_Network* structure. This call */
+      /* is the counterpart of ASC_initializeNetwork(...) which was called above. */
+      OFCondition cond = ASC_dropNetwork(&network);
+      if (cond.bad())
+      {
+        LOG(ERROR) << "Error while dropping the network: " << cond.text();
+      }
+  }
 
 
   DicomServer::DicomServer() : 
@@ -122,8 +118,7 @@
     checkCalledAet_ = true;
     clientTimeout_ = 30;
     isThreaded_ = true;
-    continue_ = false;
-    started_ = false;
+    continue_ = true;
   }
 
   DicomServer::~DicomServer()
@@ -308,14 +303,19 @@
   void DicomServer::Start()
   {
     Stop();
-    continue_ = true;
-    started_ = false;
-    pimpl_->thread_ = boost::thread(ServerThread, this);
 
-    while (!started_)
+    /* initialize network, i.e. create an instance of T_ASC_Network*. */
+    T_ASC_Network *network;
+    OFCondition cond = ASC_initializeNetwork
+      (NET_ACCEPTOR, OFstatic_cast(int, port_), /*opt_acse_timeout*/ 30, &network);
+    if (cond.bad())
     {
-      Toolbox::USleep(50000);  // Wait 50ms
+      LOG(ERROR) << "cannot create network: " << cond.text();
+      throw OrthancException(ErrorCode_DicomPortInUse);
     }
+
+    continue_ = true;
+    pimpl_->thread_ = boost::thread(ServerThread, this, network);
   }
 
 
--- a/OrthancServer/DicomProtocol/DicomServer.h	Fri Oct 02 13:31:39 2015 +0200
+++ b/OrthancServer/DicomProtocol/DicomServer.h	Fri Oct 02 13:57:54 2015 +0200
@@ -41,6 +41,8 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/noncopyable.hpp>
 
+struct T_ASC_Network;
+
 namespace Orthanc
 {
   class DicomServer : public boost::noncopyable
@@ -63,7 +65,8 @@
 
     BagOfRunnablesBySteps bagOfDispatchers_;  // This is used iff the server is threaded
 
-    static void ServerThread(DicomServer* server);
+    static void ServerThread(DicomServer* server,
+                             T_ASC_Network *net);
 
   public:
     DicomServer();
--- a/OrthancServer/main.cpp	Fri Oct 02 13:31:39 2015 +0200
+++ b/OrthancServer/main.cpp	Fri Oct 02 13:57:54 2015 +0200
@@ -572,13 +572,28 @@
   dicomServer.Start();
   LOG(WARNING) << "DICOM server listening on port: " << dicomServer.GetPortNumber();
 
-  bool restart = StartHttpServer(context, restApi, plugins);
+  bool restart;
+  ErrorCode error = ErrorCode_Success;
+
+  try
+  {
+    restart = StartHttpServer(context, restApi, plugins);
+  }
+  catch (OrthancException& e)
+  {
+    error = e.GetErrorCode();
+  }
 
   dicomServer.Stop();
   LOG(WARNING) << "    DICOM server has stopped";
 
   serverFactory.Done();
 
+  if (error != ErrorCode_Success)
+  {
+    throw OrthancException(error);
+  }
+
   return restart;
 }
 
@@ -694,7 +709,18 @@
   }
 #endif
 
-  bool restart = ConfigureHttpHandler(context, plugins);
+  bool restart;
+  ErrorCode error = ErrorCode_Success;
+
+  try
+  {
+    restart = ConfigureHttpHandler(context, plugins);
+  }
+  catch (OrthancException& e)
+  {
+    error = e.GetErrorCode();
+  }
+
   context.Stop();
 
 #if ORTHANC_PLUGINS_ENABLED == 1
@@ -704,6 +730,11 @@
   }
 #endif
 
+  if (error != ErrorCode_Success)
+  {
+    throw OrthancException(error);
+  }
+
   return restart;
 }