comparison OrthancServer/DicomProtocol/DicomServer.cpp @ 1682:6414043df7d8 db-changes

integration mainline->db-changes
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 06 Oct 2015 14:09:30 +0200
parents f079f3efe33b ee4367497d0d
children 164d78911382
comparison
equal deleted inserted replaced
1678:1a3c20cd1b53 1682:6414043df7d8
38 #include "../../Core/Toolbox.h" 38 #include "../../Core/Toolbox.h"
39 #include "../../Core/Uuid.h" 39 #include "../../Core/Uuid.h"
40 #include "../Internals/CommandDispatcher.h" 40 #include "../Internals/CommandDispatcher.h"
41 #include "../OrthancInitialization.h" 41 #include "../OrthancInitialization.h"
42 #include "EmbeddedResources.h" 42 #include "EmbeddedResources.h"
43 #include "../../Core/MultiThreading/RunnableWorkersPool.h"
43 44
44 #include <boost/thread.hpp> 45 #include <boost/thread.hpp>
45 46
46 #if defined(__linux) 47 #if defined(__linux)
47 #include <cstdlib> 48 #include <cstdlib>
50 51
51 namespace Orthanc 52 namespace Orthanc
52 { 53 {
53 struct DicomServer::PImpl 54 struct DicomServer::PImpl
54 { 55 {
55 boost::thread thread_; 56 boost::thread thread_;
56 57 T_ASC_Network *network_;
57 //std::set< 58 std::auto_ptr<RunnableWorkersPool> workers_;
58 }; 59 };
59 60
60 61
61 void DicomServer::ServerThread(DicomServer* server, 62 void DicomServer::ServerThread(DicomServer* server)
62 T_ASC_Network *network)
63 { 63 {
64 LOG(INFO) << "DICOM server started"; 64 LOG(INFO) << "DICOM server started";
65 65
66 while (server->continue_) 66 while (server->continue_)
67 { 67 {
68 /* receive an association and acknowledge or reject it. If the association was */ 68 /* receive an association and acknowledge or reject it. If the association was */
69 /* acknowledged, offer corresponding services and invoke one or more if required. */ 69 /* acknowledged, offer corresponding services and invoke one or more if required. */
70 std::auto_ptr<Internals::CommandDispatcher> dispatcher(Internals::AcceptAssociation(*server, network)); 70 std::auto_ptr<Internals::CommandDispatcher> dispatcher(Internals::AcceptAssociation(*server, server->pimpl_->network_));
71 71
72 try 72 try
73 { 73 {
74 if (dispatcher.get() != NULL) 74 if (dispatcher.get() != NULL)
75 { 75 {
76 if (server->isThreaded_) 76 server->pimpl_->workers_->Add(dispatcher.release());
77 {
78 server->bagOfDispatchers_.Add(dispatcher.release());
79 }
80 else
81 {
82 IRunnableBySteps::RunUntilDone(*dispatcher);
83 }
84 } 77 }
85 } 78 }
86 catch (OrthancException& e) 79 catch (OrthancException& e)
87 { 80 {
88 LOG(ERROR) << "Exception in the DICOM server thread: " << e.What(); 81 LOG(ERROR) << "Exception in the DICOM server thread: " << e.What();
89 } 82 }
90 } 83 }
91 84
92 LOG(INFO) << "DICOM server stopping"; 85 LOG(INFO) << "DICOM server stopping";
93
94 if (server->isThreaded_)
95 {
96 server->bagOfDispatchers_.StopAll();
97 }
98
99 /* drop the network, i.e. free memory of T_ASC_Network* structure. This call */
100 /* is the counterpart of ASC_initializeNetwork(...) which was called above. */
101 OFCondition cond = ASC_dropNetwork(&network);
102 if (cond.bad())
103 {
104 LOG(ERROR) << "Error while dropping the network: " << cond.text();
105 }
106 } 86 }
107 87
108 88
109 DicomServer::DicomServer() : 89 DicomServer::DicomServer() :
110 pimpl_(new PImpl), 90 pimpl_(new PImpl),
115 moveRequestHandlerFactory_ = NULL; 95 moveRequestHandlerFactory_ = NULL;
116 storeRequestHandlerFactory_ = NULL; 96 storeRequestHandlerFactory_ = NULL;
117 applicationEntityFilter_ = NULL; 97 applicationEntityFilter_ = NULL;
118 checkCalledAet_ = true; 98 checkCalledAet_ = true;
119 clientTimeout_ = 30; 99 clientTimeout_ = 30;
120 isThreaded_ = true; 100 continue_ = false;
121 continue_ = true;
122 } 101 }
123 102
124 DicomServer::~DicomServer() 103 DicomServer::~DicomServer()
125 { 104 {
126 if (continue_) 105 if (continue_)
137 } 116 }
138 117
139 uint16_t DicomServer::GetPortNumber() const 118 uint16_t DicomServer::GetPortNumber() const
140 { 119 {
141 return port_; 120 return port_;
142 }
143
144 void DicomServer::SetThreaded(bool isThreaded)
145 {
146 Stop();
147 isThreaded_ = isThreaded;
148 }
149
150 bool DicomServer::IsThreaded() const
151 {
152 return isThreaded_;
153 } 121 }
154 122
155 void DicomServer::SetClientTimeout(uint32_t timeout) 123 void DicomServer::SetClientTimeout(uint32_t timeout)
156 { 124 {
157 Stop(); 125 Stop();
303 void DicomServer::Start() 271 void DicomServer::Start()
304 { 272 {
305 Stop(); 273 Stop();
306 274
307 /* initialize network, i.e. create an instance of T_ASC_Network*. */ 275 /* initialize network, i.e. create an instance of T_ASC_Network*. */
308 T_ASC_Network *network;
309 OFCondition cond = ASC_initializeNetwork 276 OFCondition cond = ASC_initializeNetwork
310 (NET_ACCEPTOR, OFstatic_cast(int, port_), /*opt_acse_timeout*/ 30, &network); 277 (NET_ACCEPTOR, OFstatic_cast(int, port_), /*opt_acse_timeout*/ 30, &pimpl_->network_);
311 if (cond.bad()) 278 if (cond.bad())
312 { 279 {
313 LOG(ERROR) << "cannot create network: " << cond.text(); 280 LOG(ERROR) << "cannot create network: " << cond.text();
314 throw OrthancException(ErrorCode_DicomPortInUse); 281 throw OrthancException(ErrorCode_DicomPortInUse);
315 } 282 }
316 283
317 continue_ = true; 284 continue_ = true;
318 pimpl_->thread_ = boost::thread(ServerThread, this, network); 285 pimpl_->workers_.reset(new RunnableWorkersPool(4)); // Use 4 workers - TODO as a parameter?
286 pimpl_->thread_ = boost::thread(ServerThread, this);
319 } 287 }
320 288
321 289
322 void DicomServer::Stop() 290 void DicomServer::Stop()
323 { 291 {
328 if (pimpl_->thread_.joinable()) 296 if (pimpl_->thread_.joinable())
329 { 297 {
330 pimpl_->thread_.join(); 298 pimpl_->thread_.join();
331 } 299 }
332 300
333 bagOfDispatchers_.Finalize(); 301 pimpl_->workers_.reset(NULL);
302
303 /* drop the network, i.e. free memory of T_ASC_Network* structure. This call */
304 /* is the counterpart of ASC_initializeNetwork(...) which was called above. */
305 OFCondition cond = ASC_dropNetwork(&pimpl_->network_);
306 if (cond.bad())
307 {
308 LOG(ERROR) << "Error while dropping the network: " << cond.text();
309 }
334 } 310 }
335 } 311 }
336 312
337 313
338 bool DicomServer::IsMyAETitle(const std::string& aet) const 314 bool DicomServer::IsMyAETitle(const std::string& aet) const