comparison Plugins/Engine/OrthancPlugins.cpp @ 1595:e1e54a73ba8b

OrthancPluginRegisterRestCallbackNoLock, documentation
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 27 Aug 2015 14:58:58 +0200
parents 2bac60a4f584
children c6b50b803387
comparison
equal deleted inserted replaced
1594:2bac60a4f584 1595:e1e54a73ba8b
111 111
112 112
113 113
114 struct OrthancPlugins::PImpl 114 struct OrthancPlugins::PImpl
115 { 115 {
116 class RestCallback : public boost::noncopyable
117 {
118 private:
119 boost::regex regex_;
120 OrthancPluginRestCallback callback_;
121 bool lock_;
122
123 int32_t InvokeInternal(HttpOutput& output,
124 const std::string& flatUri,
125 const OrthancPluginHttpRequest& request)
126 {
127 return callback_(reinterpret_cast<OrthancPluginRestOutput*>(&output),
128 flatUri.c_str(),
129 &request);
130 }
131
132 public:
133 RestCallback(const char* regex,
134 OrthancPluginRestCallback callback,
135 bool lockRestCallbacks) :
136 regex_(regex),
137 callback_(callback),
138 lock_(lockRestCallbacks)
139 {
140 }
141
142 const boost::regex& GetRegularExpression() const
143 {
144 return regex_;
145 }
146
147 int32_t Invoke(boost::recursive_mutex& restCallbackMutex,
148 HttpOutput& output,
149 const std::string& flatUri,
150 const OrthancPluginHttpRequest& request)
151 {
152 if (lock_)
153 {
154 boost::recursive_mutex::scoped_lock lock(restCallbackMutex);
155 return InvokeInternal(output, flatUri, request);
156 }
157 else
158 {
159 return InvokeInternal(output, flatUri, request);
160 }
161 }
162 };
163
116 typedef std::pair<std::string, _OrthancPluginProperty> Property; 164 typedef std::pair<std::string, _OrthancPluginProperty> Property;
117 165 typedef std::list<RestCallback*> RestCallbacks;
118 typedef std::pair<boost::regex*, OrthancPluginRestCallback> RestCallback;
119 typedef std::list<RestCallback> RestCallbacks;
120 typedef std::list<OrthancPluginOnStoredInstanceCallback> OnStoredCallbacks; 166 typedef std::list<OrthancPluginOnStoredInstanceCallback> OnStoredCallbacks;
121 typedef std::list<OrthancPluginOnChangeCallback> OnChangeCallbacks; 167 typedef std::list<OrthancPluginOnChangeCallback> OnChangeCallbacks;
122 typedef std::map<Property, std::string> Properties; 168 typedef std::map<Property, std::string> Properties;
123 169
124 PluginsManager manager_; 170 PluginsManager manager_;
202 OrthancPlugins::~OrthancPlugins() 248 OrthancPlugins::~OrthancPlugins()
203 { 249 {
204 for (PImpl::RestCallbacks::iterator it = pimpl_->restCallbacks_.begin(); 250 for (PImpl::RestCallbacks::iterator it = pimpl_->restCallbacks_.begin();
205 it != pimpl_->restCallbacks_.end(); ++it) 251 it != pimpl_->restCallbacks_.end(); ++it)
206 { 252 {
207 // Delete the regular expression associated with this callback 253 delete *it;
208 delete it->first;
209 } 254 }
210 } 255 }
211 256
212 257
213 static void ArgumentsToPlugin(std::vector<const char*>& keys, 258 static void ArgumentsToPlugin(std::vector<const char*>& keys,
253 const GetArguments& getArguments, 298 const GetArguments& getArguments,
254 const char* bodyData, 299 const char* bodyData,
255 size_t bodySize) 300 size_t bodySize)
256 { 301 {
257 std::string flatUri = Toolbox::FlattenUri(uri); 302 std::string flatUri = Toolbox::FlattenUri(uri);
258 OrthancPluginRestCallback callback = NULL; 303 PImpl::RestCallback* callback = NULL;
259 304
260 std::vector<std::string> groups; 305 std::vector<std::string> groups;
261 std::vector<const char*> cgroups; 306 std::vector<const char*> cgroups;
262 307
263 // Loop over the callbacks registered by the plugins 308 // Loop over the callbacks registered by the plugins
266 it != pimpl_->restCallbacks_.end() && !found; ++it) 311 it != pimpl_->restCallbacks_.end() && !found; ++it)
267 { 312 {
268 // Check whether the regular expression associated to this 313 // Check whether the regular expression associated to this
269 // callback matches the URI 314 // callback matches the URI
270 boost::cmatch what; 315 boost::cmatch what;
271 if (boost::regex_match(flatUri.c_str(), what, *(it->first))) 316 if (boost::regex_match(flatUri.c_str(), what, (*it)->GetRegularExpression()))
272 { 317 {
273 callback = it->second; 318 callback = *it;
274 319
275 // Extract the value of the free parameters of the regular expression 320 // Extract the value of the free parameters of the regular expression
276 if (what.size() > 1) 321 if (what.size() > 1)
277 { 322 {
278 groups.resize(what.size() - 1); 323 groups.resize(what.size() - 1);
281 { 326 {
282 groups[i - 1] = what[i]; 327 groups[i - 1] = what[i];
283 cgroups[i - 1] = groups[i - 1].c_str(); 328 cgroups[i - 1] = groups[i - 1].c_str();
284 } 329 }
285 } 330 }
286 331 }
287 found = true; 332 }
288 } 333
289 } 334 if (callback == NULL)
290 335 {
291 if (!found) 336 // Callback not found
292 {
293 return false; 337 return false;
294 } 338 }
295 339
296 LOG(INFO) << "Delegating HTTP request to plugin for URI: " << flatUri; 340 LOG(INFO) << "Delegating HTTP request to plugin for URI: " << flatUri;
297 341
344 request.headersKeys = &headersKeys[0]; 388 request.headersKeys = &headersKeys[0];
345 request.headersValues = &headersValues[0]; 389 request.headersValues = &headersValues[0];
346 } 390 }
347 391
348 assert(callback != NULL); 392 assert(callback != NULL);
349 int32_t error; 393 int32_t error = callback->Invoke(pimpl_->restCallbackMutex_, output, flatUri, request);
350
351 {
352 boost::recursive_mutex::scoped_lock lock(pimpl_->restCallbackMutex_);
353 error = callback(reinterpret_cast<OrthancPluginRestOutput*>(&output),
354 flatUri.c_str(),
355 &request);
356 }
357 394
358 if (error == 0 && 395 if (error == 0 &&
359 output.IsWritingMultipart()) 396 output.IsWritingMultipart())
360 { 397 {
361 output.CloseMultipart(); 398 output.CloseMultipart();
457 CopyToMemoryBuffer(target, str.c_str(), str.size()); 494 CopyToMemoryBuffer(target, str.c_str(), str.size());
458 } 495 }
459 } 496 }
460 497
461 498
462 void OrthancPlugins::RegisterRestCallback(const void* parameters) 499 void OrthancPlugins::RegisterRestCallback(const void* parameters,
500 bool lock)
463 { 501 {
464 const _OrthancPluginRestCallback& p = 502 const _OrthancPluginRestCallback& p =
465 *reinterpret_cast<const _OrthancPluginRestCallback*>(parameters); 503 *reinterpret_cast<const _OrthancPluginRestCallback*>(parameters);
466 504
467 LOG(INFO) << "Plugin has registered a REST callback on: " << p.pathRegularExpression; 505 LOG(INFO) << "Plugin has registered a REST callback "
468 pimpl_->restCallbacks_.push_back(std::make_pair(new boost::regex(p.pathRegularExpression), p.callback)); 506 << (lock ? "with" : "witout")
507 << " mutual exclusion on: "
508 << p.pathRegularExpression;
509
510 pimpl_->restCallbacks_.push_back(new PImpl::RestCallback(p.pathRegularExpression, p.callback, lock));
469 } 511 }
470 512
471 513
472 514
473 void OrthancPlugins::RegisterOnStoredInstanceCallback(const void* parameters) 515 void OrthancPlugins::RegisterOnStoredInstanceCallback(const void* parameters)
993 case _OrthancPluginService_BufferCompression: 1035 case _OrthancPluginService_BufferCompression:
994 BufferCompression(parameters); 1036 BufferCompression(parameters);
995 return true; 1037 return true;
996 1038
997 case _OrthancPluginService_RegisterRestCallback: 1039 case _OrthancPluginService_RegisterRestCallback:
998 RegisterRestCallback(parameters); 1040 RegisterRestCallback(parameters, true);
1041 return true;
1042
1043 case _OrthancPluginService_RegisterRestCallbackNoLock:
1044 RegisterRestCallback(parameters, false);
999 return true; 1045 return true;
1000 1046
1001 case _OrthancPluginService_RegisterOnStoredInstanceCallback: 1047 case _OrthancPluginService_RegisterOnStoredInstanceCallback:
1002 RegisterOnStoredInstanceCallback(parameters); 1048 RegisterOnStoredInstanceCallback(parameters);
1003 return true; 1049 return true;