# HG changeset patch # User Sebastien Jodogne # Date 1443787074 -7200 # Node ID 131136aeeaa7175cfd26b69dd88f7faddebf3f9d # Parent 4fc502d469f4f0b56b367bb1abacef82b1743f4f improved exception handling in the main program diff -r 4fc502d469f4 -r 131136aeeaa7 OrthancServer/DicomProtocol/DicomServer.cpp --- 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 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 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); } diff -r 4fc502d469f4 -r 131136aeeaa7 OrthancServer/DicomProtocol/DicomServer.h --- 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 #include +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(); diff -r 4fc502d469f4 -r 131136aeeaa7 OrthancServer/main.cpp --- 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; }