Mercurial > hg > orthanc
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 |