comparison OrthancServer/Plugins/Engine/OrthancPlugins.cpp @ 4459:16392fe89ce0

new mutex to protect registration of REST callbacks: restCallbackRegistrationMutex_
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 20 Jan 2021 13:30:54 +0100
parents 453cd3a5a0da
children c1f36fd13730
comparison
equal deleted inserted replaced
4458:e4dae17035b9 4459:16392fe89ce0
865 class RestCallback : public boost::noncopyable 865 class RestCallback : public boost::noncopyable
866 { 866 {
867 private: 867 private:
868 boost::regex regex_; 868 boost::regex regex_;
869 OrthancPluginRestCallback callback_; 869 OrthancPluginRestCallback callback_;
870 bool lock_; 870 bool mutualExclusion_;
871 871
872 OrthancPluginErrorCode InvokeInternal(PluginHttpOutput& output, 872 OrthancPluginErrorCode InvokeInternal(PluginHttpOutput& output,
873 const std::string& flatUri, 873 const std::string& flatUri,
874 const OrthancPluginHttpRequest& request) 874 const OrthancPluginHttpRequest& request)
875 { 875 {
879 } 879 }
880 880
881 public: 881 public:
882 RestCallback(const char* regex, 882 RestCallback(const char* regex,
883 OrthancPluginRestCallback callback, 883 OrthancPluginRestCallback callback,
884 bool lockRestCallbacks) : 884 bool mutualExclusion) :
885 regex_(regex), 885 regex_(regex),
886 callback_(callback), 886 callback_(callback),
887 lock_(lockRestCallbacks) 887 mutualExclusion_(mutualExclusion)
888 { 888 {
889 } 889 }
890 890
891 const boost::regex& GetRegularExpression() const 891 const boost::regex& GetRegularExpression() const
892 { 892 {
893 return regex_; 893 return regex_;
894 } 894 }
895 895
896 OrthancPluginErrorCode Invoke(boost::recursive_mutex& restCallbackMutex, 896 OrthancPluginErrorCode Invoke(boost::recursive_mutex& invokationMutex,
897 PluginHttpOutput& output, 897 PluginHttpOutput& output,
898 const std::string& flatUri, 898 const std::string& flatUri,
899 const OrthancPluginHttpRequest& request) 899 const OrthancPluginHttpRequest& request)
900 { 900 {
901 if (lock_) 901 if (mutualExclusion_)
902 { 902 {
903 boost::recursive_mutex::scoped_lock lock(restCallbackMutex); 903 boost::recursive_mutex::scoped_lock lock(invokationMutex);
904 return InvokeInternal(output, flatUri, request); 904 return InvokeInternal(output, flatUri, request);
905 } 905 }
906 else 906 else
907 { 907 {
908 return InvokeInternal(output, flatUri, request); 908 return InvokeInternal(output, flatUri, request);
1106 RefreshMetricsCallbacks refreshMetricsCallbacks_; 1106 RefreshMetricsCallbacks refreshMetricsCallbacks_;
1107 StorageCommitmentScpCallbacks storageCommitmentScpCallbacks_; 1107 StorageCommitmentScpCallbacks storageCommitmentScpCallbacks_;
1108 std::unique_ptr<StorageAreaFactory> storageArea_; 1108 std::unique_ptr<StorageAreaFactory> storageArea_;
1109 std::set<std::string> authorizationTokens_; 1109 std::set<std::string> authorizationTokens_;
1110 1110
1111 boost::recursive_mutex restCallbackMutex_; 1111 boost::recursive_mutex restCallbackInvokationMutex_;
1112 boost::shared_mutex restCallbackRegistrationMutex_; // New in Orthanc 1.9.0
1112 boost::recursive_mutex storedCallbackMutex_; 1113 boost::recursive_mutex storedCallbackMutex_;
1113 boost::recursive_mutex changeCallbackMutex_; 1114 boost::recursive_mutex changeCallbackMutex_;
1114 boost::mutex findCallbackMutex_; 1115 boost::mutex findCallbackMutex_;
1115 boost::mutex worklistCallbackMutex_; 1116 boost::mutex worklistCallbackMutex_;
1116 boost::shared_mutex decoderTranscoderMutex_; // Changed from "boost::mutex" in Orthanc 1.7.0 1117 boost::shared_mutex decoderTranscoderMutex_; // Changed from "boost::mutex" in Orthanc 1.7.0
1910 RestCallbackMatcher matcher(uri); 1911 RestCallbackMatcher matcher(uri);
1911 1912
1912 PImpl::ChunkedRestCallback* callback = NULL; 1913 PImpl::ChunkedRestCallback* callback = NULL;
1913 1914
1914 // Loop over the callbacks registered by the plugins 1915 // Loop over the callbacks registered by the plugins
1916 boost::shared_lock<boost::shared_mutex> lock(pimpl_->restCallbackRegistrationMutex_);
1915 for (PImpl::ChunkedRestCallbacks::const_iterator it = pimpl_->chunkedRestCallbacks_.begin(); 1917 for (PImpl::ChunkedRestCallbacks::const_iterator it = pimpl_->chunkedRestCallbacks_.begin();
1916 it != pimpl_->chunkedRestCallbacks_.end(); ++it) 1918 it != pimpl_->chunkedRestCallbacks_.end(); ++it)
1917 { 1919 {
1918 if (matcher.IsMatch((*it)->GetRegularExpression())) 1920 if (matcher.IsMatch((*it)->GetRegularExpression()))
1919 { 1921 {
1984 RestCallbackMatcher matcher(uri); 1986 RestCallbackMatcher matcher(uri);
1985 1987
1986 PImpl::RestCallback* callback = NULL; 1988 PImpl::RestCallback* callback = NULL;
1987 1989
1988 // Loop over the callbacks registered by the plugins 1990 // Loop over the callbacks registered by the plugins
1991 boost::shared_lock<boost::shared_mutex> lock(pimpl_->restCallbackRegistrationMutex_);
1989 for (PImpl::RestCallbacks::const_iterator it = pimpl_->restCallbacks_.begin(); 1992 for (PImpl::RestCallbacks::const_iterator it = pimpl_->restCallbacks_.begin();
1990 it != pimpl_->restCallbacks_.end(); ++it) 1993 it != pimpl_->restCallbacks_.end(); ++it)
1991 { 1994 {
1992 if (matcher.IsMatch((*it)->GetRegularExpression())) 1995 if (matcher.IsMatch((*it)->GetRegularExpression()))
1993 { 1996 {
2011 2014
2012 PImpl::PluginHttpOutput pluginOutput(output); 2015 PImpl::PluginHttpOutput pluginOutput(output);
2013 2016
2014 assert(callback != NULL); 2017 assert(callback != NULL);
2015 OrthancPluginErrorCode error = callback->Invoke 2018 OrthancPluginErrorCode error = callback->Invoke
2016 (pimpl_->restCallbackMutex_, pluginOutput, matcher.GetFlatUri(), converter.GetRequest()); 2019 (pimpl_->restCallbackInvokationMutex_, pluginOutput, matcher.GetFlatUri(), converter.GetRequest());
2017 2020
2018 pluginOutput.Close(error, GetErrorDictionary()); 2021 pluginOutput.Close(error, GetErrorDictionary());
2019 return true; 2022 return true;
2020 } 2023 }
2021 2024
2192 } 2195 }
2193 2196
2194 2197
2195 2198
2196 void OrthancPlugins::RegisterRestCallback(const void* parameters, 2199 void OrthancPlugins::RegisterRestCallback(const void* parameters,
2197 bool lock) 2200 bool mutualExclusion)
2198 { 2201 {
2199 const _OrthancPluginRestCallback& p = 2202 const _OrthancPluginRestCallback& p =
2200 *reinterpret_cast<const _OrthancPluginRestCallback*>(parameters); 2203 *reinterpret_cast<const _OrthancPluginRestCallback*>(parameters);
2201 2204
2202 CLOG(INFO, PLUGINS) << "Plugin has registered a REST callback " 2205 CLOG(INFO, PLUGINS) << "Plugin has registered a REST callback "
2203 << (lock ? "with" : "without") 2206 << (mutualExclusion ? "with" : "without")
2204 << " mutual exclusion on: " 2207 << " mutual exclusion on: "
2205 << p.pathRegularExpression; 2208 << p.pathRegularExpression;
2206 2209
2207 pimpl_->restCallbacks_.push_back(new PImpl::RestCallback(p.pathRegularExpression, p.callback, lock)); 2210 {
2211 boost::unique_lock<boost::shared_mutex> lock(pimpl_->restCallbackRegistrationMutex_);
2212 pimpl_->restCallbacks_.push_back(new PImpl::RestCallback(p.pathRegularExpression, p.callback, mutualExclusion));
2213 }
2208 } 2214 }
2209 2215
2210 2216
2211 void OrthancPlugins::RegisterChunkedRestCallback(const void* parameters) 2217 void OrthancPlugins::RegisterChunkedRestCallback(const void* parameters)
2212 { 2218 {
2214 *reinterpret_cast<const _OrthancPluginChunkedRestCallback*>(parameters); 2220 *reinterpret_cast<const _OrthancPluginChunkedRestCallback*>(parameters);
2215 2221
2216 CLOG(INFO, PLUGINS) << "Plugin has registered a REST callback for chunked streams on: " 2222 CLOG(INFO, PLUGINS) << "Plugin has registered a REST callback for chunked streams on: "
2217 << p.pathRegularExpression; 2223 << p.pathRegularExpression;
2218 2224
2219 pimpl_->chunkedRestCallbacks_.push_back(new PImpl::ChunkedRestCallback(p)); 2225 {
2226 boost::unique_lock<boost::shared_mutex> lock(pimpl_->restCallbackRegistrationMutex_);
2227 pimpl_->chunkedRestCallbacks_.push_back(new PImpl::ChunkedRestCallback(p));
2228 }
2220 } 2229 }
2221 2230
2222 2231
2223 void OrthancPlugins::RegisterOnStoredInstanceCallback(const void* parameters) 2232 void OrthancPlugins::RegisterOnStoredInstanceCallback(const void* parameters)
2224 { 2233 {
5324 RestCallbackMatcher matcher(uri); 5333 RestCallbackMatcher matcher(uri);
5325 5334
5326 PImpl::ChunkedRestCallback* callback = NULL; 5335 PImpl::ChunkedRestCallback* callback = NULL;
5327 5336
5328 // Loop over the callbacks registered by the plugins 5337 // Loop over the callbacks registered by the plugins
5338 boost::shared_lock<boost::shared_mutex> lock(pimpl_->restCallbackRegistrationMutex_);
5329 for (PImpl::ChunkedRestCallbacks::const_iterator it = pimpl_->chunkedRestCallbacks_.begin(); 5339 for (PImpl::ChunkedRestCallbacks::const_iterator it = pimpl_->chunkedRestCallbacks_.begin();
5330 it != pimpl_->chunkedRestCallbacks_.end(); ++it) 5340 it != pimpl_->chunkedRestCallbacks_.end(); ++it)
5331 { 5341 {
5332 if (matcher.IsMatch((*it)->GetRegularExpression())) 5342 if (matcher.IsMatch((*it)->GetRegularExpression()))
5333 { 5343 {