# HG changeset patch # User Sebastien Jodogne # Date 1404397636 -7200 # Node ID cf52f3bcb2b3d71f714fded31ca6e46ad3330edc # Parent 8c67382f44a7cb80703fb2b44abaecd7d07b628c clarification of Lua classes wrt multithreading diff -r 8c67382f44a7 -r cf52f3bcb2b3 Core/Lua/LuaContext.cpp --- a/Core/Lua/LuaContext.cpp Thu Jul 03 15:58:53 2014 +0200 +++ b/Core/Lua/LuaContext.cpp Thu Jul 03 16:27:16 2014 +0200 @@ -34,6 +34,7 @@ #include "LuaContext.h" #include +#include extern "C" { @@ -111,8 +112,6 @@ void LuaContext::Execute(std::string* output, const std::string& command) { - boost::mutex::scoped_lock lock(mutex_); - log_.clear(); int error = (luaL_loadbuffer(lua_, command.c_str(), command.size(), "line") || lua_pcall(lua_, 0, 0, 0)); @@ -143,7 +142,6 @@ bool LuaContext::IsExistingFunction(const char* name) { - boost::mutex::scoped_lock lock(mutex_); lua_settop(lua_, 0); lua_getglobal(lua_, name); return lua_type(lua_, -1) == LUA_TFUNCTION; diff -r 8c67382f44a7 -r cf52f3bcb2b3 Core/Lua/LuaContext.h --- a/Core/Lua/LuaContext.h Thu Jul 03 15:58:53 2014 +0200 +++ b/Core/Lua/LuaContext.h Thu Jul 03 16:27:16 2014 +0200 @@ -34,8 +34,6 @@ #include "LuaException.h" -#include - extern "C" { #include @@ -43,6 +41,7 @@ #include +#include namespace Orthanc { @@ -52,7 +51,6 @@ friend class LuaFunctionCall; lua_State *lua_; - boost::mutex mutex_; std::string log_; static int PrintToLog(lua_State *L); diff -r 8c67382f44a7 -r cf52f3bcb2b3 Core/Lua/LuaFunctionCall.cpp --- a/Core/Lua/LuaFunctionCall.cpp Thu Jul 03 15:58:53 2014 +0200 +++ b/Core/Lua/LuaFunctionCall.cpp Thu Jul 03 16:27:16 2014 +0200 @@ -33,6 +33,8 @@ #include "../PrecompiledHeaders.h" #include "LuaFunctionCall.h" +#include + namespace Orthanc { @@ -47,7 +49,6 @@ LuaFunctionCall::LuaFunctionCall(LuaContext& context, const char* functionName) : context_(context), - lock_(context.mutex_), isExecuted_(false) { // Clear the stack to fulfill the invariant diff -r 8c67382f44a7 -r cf52f3bcb2b3 Core/Lua/LuaFunctionCall.h --- a/Core/Lua/LuaFunctionCall.h Thu Jul 03 15:58:53 2014 +0200 +++ b/Core/Lua/LuaFunctionCall.h Thu Jul 03 16:27:16 2014 +0200 @@ -36,14 +36,12 @@ #include - namespace Orthanc { class LuaFunctionCall : public boost::noncopyable { private: LuaContext& context_; - boost::mutex::scoped_lock lock_; bool isExecuted_; void CheckAlreadyExecuted(); diff -r 8c67382f44a7 -r cf52f3bcb2b3 OrthancServer/OrthancRestApi/OrthancRestSystem.cpp --- a/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp Thu Jul 03 15:58:53 2014 +0200 +++ b/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp Thu Jul 03 16:27:16 2014 +0200 @@ -90,7 +90,12 @@ { std::string result; ServerContext& context = OrthancRestApi::GetContext(call); - context.GetLuaContext().Execute(result, call.GetPostBody()); + + { + ServerContext::LuaContextLocker locker(context); + locker.GetLua().Execute(result, call.GetPostBody()); + } + call.GetOutput().AnswerBuffer(result, "text/plain"); } diff -r 8c67382f44a7 -r cf52f3bcb2b3 OrthancServer/ServerContext.cpp --- a/OrthancServer/ServerContext.cpp Thu Jul 03 15:58:53 2014 +0200 +++ b/OrthancServer/ServerContext.cpp Thu Jul 03 16:27:16 2014 +0200 @@ -46,6 +46,7 @@ #define ENABLE_DICOM_CACHE 1 static const char* RECEIVED_INSTANCE_FILTER = "ReceivedInstanceFilter"; +static const char* ON_STORED_INSTANCE = "OnStoredInstance"; static const size_t DICOM_CACHE_SIZE = 2; @@ -91,6 +92,31 @@ storage_.Remove(fileUuid); } + + bool ServerContext::ApplyReceivedInstanceFilter(const Json::Value& dicomJson, + const std::string& remoteAet) + { + LuaContextLocker locker(*this); + + if (locker.GetLua().IsExistingFunction(RECEIVED_INSTANCE_FILTER)) + { + Json::Value simplified; + SimplifyTags(simplified, dicomJson); + + LuaFunctionCall call(locker.GetLua(), RECEIVED_INSTANCE_FILTER); + call.PushJSON(simplified); + call.PushString(remoteAet); + + if (!call.ExecutePredicate()) + { + return false; + } + } + + return true; + } + + StoreStatus ServerContext::Store(const char* dicomInstance, size_t dicomSize, const DicomMap& dicomSummary, @@ -98,20 +124,10 @@ const std::string& remoteAet) { // Test if the instance must be filtered out - if (lua_.IsExistingFunction(RECEIVED_INSTANCE_FILTER)) + if (!ApplyReceivedInstanceFilter(dicomJson, remoteAet)) { - Json::Value simplified; - SimplifyTags(simplified, dicomJson); - - LuaFunctionCall call(lua_, RECEIVED_INSTANCE_FILTER); - call.PushJSON(simplified); - call.PushString(remoteAet); - - if (!call.ExecutePredicate()) - { - LOG(INFO) << "An incoming instance has been discarded by the filter"; - return StoreStatus_FilteredOut; - } + LOG(INFO) << "An incoming instance has been discarded by the filter"; + return StoreStatus_FilteredOut; } if (compressionEnabled_) diff -r 8c67382f44a7 -r cf52f3bcb2b3 OrthancServer/ServerContext.h --- a/OrthancServer/ServerContext.h Thu Jul 03 15:58:53 2014 +0200 +++ b/OrthancServer/ServerContext.h Thu Jul 03 16:27:16 2014 +0200 @@ -65,6 +65,9 @@ virtual IDynamicObject* Provide(const std::string& id); }; + bool ApplyReceivedInstanceFilter(const Json::Value& dicomJson, + const std::string& remoteAet); + FileStorage storage_; ServerIndex index_; CompressedFileStorageAccessor accessor_; @@ -76,10 +79,11 @@ ReusableDicomUserConnection scu_; ServerScheduler scheduler_; + boost::mutex luaMutex_; LuaContext lua_; public: - class DicomCacheLocker + class DicomCacheLocker : public boost::noncopyable { private: ServerContext& that_; @@ -97,6 +101,28 @@ } }; + class LuaContextLocker : public boost::noncopyable + { + private: + ServerContext& that_; + + public: + LuaContextLocker(ServerContext& that) : that_(that) + { + that.luaMutex_.lock(); + } + + ~LuaContextLocker() + { + that_.luaMutex_.unlock(); + } + + LuaContext& GetLua() + { + return that_.lua_; + } + }; + ServerContext(const boost::filesystem::path& storagePath, const boost::filesystem::path& indexPath); @@ -153,11 +179,6 @@ FileContentType content, bool uncompressIfNeeded = true); - LuaContext& GetLuaContext() - { - return lua_; - } - void SetStoreMD5ForAttachments(bool storeMD5); bool IsStoreMD5ForAttachments() const diff -r 8c67382f44a7 -r cf52f3bcb2b3 OrthancServer/main.cpp --- a/OrthancServer/main.cpp Thu Jul 03 15:58:53 2014 +0200 +++ b/OrthancServer/main.cpp Thu Jul 03 16:27:16 2014 +0200 @@ -186,10 +186,12 @@ { static const char* HTTP_FILTER = "IncomingHttpRequestFilter"; + ServerContext::LuaContextLocker locker(context_); + // Test if the instance must be filtered out - if (context_.GetLuaContext().IsExistingFunction(HTTP_FILTER)) + if (locker.GetLua().IsExistingFunction(HTTP_FILTER)) { - LuaFunctionCall call(context_.GetLuaContext(), HTTP_FILTER); + LuaFunctionCall call(locker.GetLua(), HTTP_FILTER); switch (method) { @@ -371,7 +373,9 @@ LOG(WARNING) << "Installing the Lua scripts from: " << path; std::string script; Toolbox::ReadFile(script, path); - context.GetLuaContext().Execute(script); + + ServerContext::LuaContextLocker locker(context); + locker.GetLua().Execute(script); }