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;