Mercurial > hg > orthanc
comparison Plugins/Engine/OrthancPlugins.cpp @ 1436:0a3e3be59094
uncoupling of SignalChange for Lua scripts
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 30 Jun 2015 17:19:26 +0200 |
parents | f9cd40166269 |
children | 02f5a3f5c0a0 |
comparison
equal
deleted
inserted
replaced
1435:6406f5493d92 | 1436:0a3e3be59094 |
---|---|
33 #include "OrthancPlugins.h" | 33 #include "OrthancPlugins.h" |
34 | 34 |
35 #include "../../Core/ChunkedBuffer.h" | 35 #include "../../Core/ChunkedBuffer.h" |
36 #include "../../Core/HttpServer/HttpOutput.h" | 36 #include "../../Core/HttpServer/HttpOutput.h" |
37 #include "../../Core/ImageFormats/PngWriter.h" | 37 #include "../../Core/ImageFormats/PngWriter.h" |
38 #include "../../Core/MultiThreading/SharedMessageQueue.h" | |
39 #include "../../Core/OrthancException.h" | 38 #include "../../Core/OrthancException.h" |
40 #include "../../Core/Toolbox.h" | 39 #include "../../Core/Toolbox.h" |
41 #include "../../OrthancServer/OrthancInitialization.h" | 40 #include "../../OrthancServer/OrthancInitialization.h" |
42 #include "../../OrthancServer/OrthancRestApi/OrthancRestApi.h" | 41 #include "../../OrthancServer/OrthancRestApi/OrthancRestApi.h" |
43 #include "../../OrthancServer/ServerContext.h" | 42 #include "../../OrthancServer/ServerContext.h" |
44 #include "../../OrthancServer/ServerToolbox.h" | 43 #include "../../OrthancServer/ServerToolbox.h" |
45 | 44 |
46 #include <boost/thread.hpp> | |
47 #include <boost/regex.hpp> | 45 #include <boost/regex.hpp> |
48 #include <glog/logging.h> | 46 #include <glog/logging.h> |
49 | 47 |
50 namespace Orthanc | 48 namespace Orthanc |
51 { | 49 { |
136 virtual void Send(bool isHeader, const void* buffer, size_t length) | 134 virtual void Send(bool isHeader, const void* buffer, size_t length) |
137 { | 135 { |
138 if (!isHeader) | 136 if (!isHeader) |
139 { | 137 { |
140 buffer_.AddChunk(reinterpret_cast<const char*>(buffer), length); | 138 buffer_.AddChunk(reinterpret_cast<const char*>(buffer), length); |
141 } | |
142 } | |
143 }; | |
144 | |
145 | |
146 class PendingChange : public IDynamicObject | |
147 { | |
148 private: | |
149 OrthancPluginChangeType changeType_; | |
150 OrthancPluginResourceType resourceType_; | |
151 std::string publicId_; | |
152 | |
153 public: | |
154 PendingChange(const ServerIndexChange& change) | |
155 { | |
156 changeType_ = Convert(change.GetChangeType()); | |
157 resourceType_ = Convert(change.GetResourceType()); | |
158 publicId_ = change.GetPublicId(); | |
159 } | |
160 | |
161 void Submit(std::list<OrthancPluginOnChangeCallback>& callbacks) | |
162 { | |
163 for (std::list<OrthancPluginOnChangeCallback>::const_iterator | |
164 callback = callbacks.begin(); | |
165 callback != callbacks.end(); ++callback) | |
166 { | |
167 (*callback) (changeType_, resourceType_, publicId_.c_str()); | |
168 } | 139 } |
169 } | 140 } |
170 }; | 141 }; |
171 } | 142 } |
172 | 143 |
189 OnStoredCallbacks onStoredCallbacks_; | 160 OnStoredCallbacks onStoredCallbacks_; |
190 OnChangeCallbacks onChangeCallbacks_; | 161 OnChangeCallbacks onChangeCallbacks_; |
191 bool hasStorageArea_; | 162 bool hasStorageArea_; |
192 _OrthancPluginRegisterStorageArea storageArea_; | 163 _OrthancPluginRegisterStorageArea storageArea_; |
193 boost::recursive_mutex callbackMutex_; | 164 boost::recursive_mutex callbackMutex_; |
194 SharedMessageQueue pendingChanges_; | |
195 boost::thread changeThread_; | |
196 bool done_; | |
197 Properties properties_; | 165 Properties properties_; |
198 int argc_; | 166 int argc_; |
199 char** argv_; | 167 char** argv_; |
200 std::auto_ptr<OrthancPluginDatabase> database_; | 168 std::auto_ptr<OrthancPluginDatabase> database_; |
201 | 169 |
202 PImpl() : | 170 PImpl() : |
203 context_(NULL), | 171 context_(NULL), |
204 restApi_(NULL), | 172 restApi_(NULL), |
205 hasStorageArea_(false), | 173 hasStorageArea_(false), |
206 done_(false), | |
207 argc_(1), | 174 argc_(1), |
208 argv_(NULL) | 175 argv_(NULL) |
209 { | 176 { |
210 memset(&storageArea_, 0, sizeof(storageArea_)); | 177 memset(&storageArea_, 0, sizeof(storageArea_)); |
211 } | 178 } |
212 | |
213 | |
214 static void ChangeThread(PImpl* that) | |
215 { | |
216 while (!that->done_) | |
217 { | |
218 std::auto_ptr<IDynamicObject> obj(that->pendingChanges_.Dequeue(500)); | |
219 | |
220 if (obj.get() != NULL) | |
221 { | |
222 boost::recursive_mutex::scoped_lock lock(that->callbackMutex_); | |
223 PendingChange& change = *dynamic_cast<PendingChange*>(obj.get()); | |
224 change.Submit(that->onChangeCallbacks_); | |
225 } | |
226 } | |
227 } | |
228 }; | 179 }; |
229 | 180 |
230 | 181 |
231 | 182 |
232 static char* CopyString(const std::string& str) | 183 static char* CopyString(const std::string& str) |
252 | 203 |
253 OrthancPlugins::OrthancPlugins() | 204 OrthancPlugins::OrthancPlugins() |
254 { | 205 { |
255 pimpl_.reset(new PImpl()); | 206 pimpl_.reset(new PImpl()); |
256 pimpl_->manager_.RegisterServiceProvider(*this); | 207 pimpl_->manager_.RegisterServiceProvider(*this); |
257 pimpl_->changeThread_ = boost::thread(PImpl::ChangeThread, pimpl_.get()); | |
258 } | 208 } |
259 | 209 |
260 | 210 |
261 void OrthancPlugins::SetServerContext(ServerContext& context) | 211 void OrthancPlugins::SetServerContext(ServerContext& context) |
262 { | 212 { |
265 | 215 |
266 | 216 |
267 | 217 |
268 OrthancPlugins::~OrthancPlugins() | 218 OrthancPlugins::~OrthancPlugins() |
269 { | 219 { |
270 Stop(); | |
271 | |
272 for (PImpl::RestCallbacks::iterator it = pimpl_->restCallbacks_.begin(); | 220 for (PImpl::RestCallbacks::iterator it = pimpl_->restCallbacks_.begin(); |
273 it != pimpl_->restCallbacks_.end(); ++it) | 221 it != pimpl_->restCallbacks_.end(); ++it) |
274 { | 222 { |
275 // Delete the regular expression associated with this callback | 223 // Delete the regular expression associated with this callback |
276 delete it->first; | 224 delete it->first; |
277 } | 225 } |
278 } | 226 } |
279 | |
280 | |
281 void OrthancPlugins::Stop() | |
282 { | |
283 if (!pimpl_->done_) | |
284 { | |
285 pimpl_->done_ = true; | |
286 pimpl_->changeThread_.join(); | |
287 } | |
288 } | |
289 | |
290 | 227 |
291 | 228 |
292 static void ArgumentsToPlugin(std::vector<const char*>& keys, | 229 static void ArgumentsToPlugin(std::vector<const char*>& keys, |
293 std::vector<const char*>& values, | 230 std::vector<const char*>& values, |
294 const HttpHandler::Arguments& arguments) | 231 const HttpHandler::Arguments& arguments) |
472 | 409 |
473 void OrthancPlugins::SignalChange(const ServerIndexChange& change) | 410 void OrthancPlugins::SignalChange(const ServerIndexChange& change) |
474 { | 411 { |
475 try | 412 try |
476 { | 413 { |
477 pimpl_->pendingChanges_.Enqueue(new PendingChange(change)); | 414 boost::recursive_mutex::scoped_lock lock(pimpl_->callbackMutex_); |
415 | |
416 for (std::list<OrthancPluginOnChangeCallback>::const_iterator | |
417 callback = pimpl_->onChangeCallbacks_.begin(); | |
418 callback != pimpl_->onChangeCallbacks_.end(); ++callback) | |
419 { | |
420 (*callback) (Convert(change.GetChangeType()), | |
421 Convert(change.GetResourceType()), | |
422 change.GetPublicId().c_str()); | |
423 } | |
478 } | 424 } |
479 catch (OrthancException&) | 425 catch (OrthancException&) |
480 { | 426 { |
481 // This change type or resource type is not supported by the plugin SDK | 427 // This change type or resource type is not supported by the plugin SDK |
482 return; | 428 return; |