Mercurial > hg > orthanc
diff OrthancServer/ServerJobs/LuaJobManager.cpp @ 2604:76ef12fa136c jobs
fix race conditions if creating Lua jobs
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 18 May 2018 17:37:14 +0200 |
parents | 988936118354 |
children | 1e11b0229e04 |
line wrap: on
line diff
--- a/OrthancServer/ServerJobs/LuaJobManager.cpp Fri May 18 17:02:25 2018 +0200 +++ b/OrthancServer/ServerJobs/LuaJobManager.cpp Fri May 18 17:37:14 2018 +0200 @@ -34,6 +34,13 @@ #include "../PrecompiledHeadersServer.h" #include "LuaJobManager.h" +#include "DeleteResourceOperation.h" +#include "StoreScuOperation.h" +#include "../../Core/JobsEngine/Operations/LogJobOperation.h" + +#include "DicomInstanceOperationValue.h" +#include "../../Core/JobsEngine/Operations/NullOperationValue.h" +#include "../../Core/JobsEngine/Operations/StringOperationValue.h" namespace Orthanc { @@ -59,8 +66,7 @@ } - LuaJobManager::LuaJobManager(JobsEngine& engine) : - engine_(engine), + LuaJobManager::LuaJobManager() : currentJob_(NULL), maxOperations_(1000), priority_(0), @@ -102,30 +108,108 @@ } - LuaJobManager::Lock* LuaJobManager::Modify() + LuaJobManager::Lock::Lock(LuaJobManager& that, + JobsEngine& engine) : + that_(that), + lock_(that.mutex_), + engine_(engine) { - boost::mutex::scoped_lock lock(mutex_); - - if (currentJob_ != NULL) + if (that_.currentJob_ == NULL) + { + isNewJob_ = true; + } + else { - std::auto_ptr<Lock> result(new Lock(*currentJob_)); + jobLock_.reset(new SequenceOfOperationsJob::Lock(*that_.currentJob_)); - if (!result->IsDone() && - result->GetOperationsCount() < maxOperations_) + if (jobLock_->IsDone() || + jobLock_->GetOperationsCount() >= that_.maxOperations_) { - return result.release(); + jobLock_.reset(NULL); + isNewJob_ = true; + } + else + { + isNewJob_ = false; } } - // Need to create a new job, as the previous one is either - // finished, or is getting too long - currentJob_ = new SequenceOfOperationsJob; + if (isNewJob_) + { + // Need to create a new job, as the previous one is either + // finished, or is getting too long + that_.currentJob_ = new SequenceOfOperationsJob; + jobLock_.reset(new SequenceOfOperationsJob::Lock(*that_.currentJob_)); + jobLock_->SetTrailingOperationTimeout(that_.trailingTimeout_); + } + + assert(jobLock_.get() != NULL); + } + + + LuaJobManager::Lock::~Lock() + { + assert(jobLock_.get() != NULL); + jobLock_.reset(NULL); + + if (isNewJob_) + { + engine_.GetRegistry().Submit(that_.currentId_, that_.currentJob_, that_.priority_); + } + } + + + size_t LuaJobManager::Lock::AddDeleteResourceOperation(ServerContext& context) + { + assert(jobLock_.get() != NULL); + return jobLock_->AddOperation(new DeleteResourceOperation(context)); + } + + + size_t LuaJobManager::Lock::AddLogOperation() + { + assert(jobLock_.get() != NULL); + return jobLock_->AddOperation(new LogJobOperation); + } + - engine_.GetRegistry().Submit(currentId_, currentJob_, priority_); + size_t LuaJobManager::Lock::AddStoreScuOperation(const std::string& localAet, + const RemoteModalityParameters& modality, + IDicomConnectionManager& manager) + { + assert(jobLock_.get() != NULL); + return jobLock_->AddOperation(new StoreScuOperation(localAet, modality, that_.connectionManager_)); + } + + + void LuaJobManager::Lock::AddNullInput(size_t operation) + { + assert(jobLock_.get() != NULL); + jobLock_->AddInput(operation, NullOperationValue()); + } + - std::auto_ptr<Lock> result(new Lock(*currentJob_)); - result->SetTrailingOperationTimeout(trailingTimeout_); + void LuaJobManager::Lock::AddStringInput(size_t operation, + const std::string& content) + { + assert(jobLock_.get() != NULL); + jobLock_->AddInput(operation, StringOperationValue(content)); + } + - return result.release(); + void LuaJobManager::Lock::AddDicomInstanceInput(size_t operation, + ServerContext& context, + const std::string& instanceId) + { + assert(jobLock_.get() != NULL); + jobLock_->AddInput(operation, DicomInstanceOperationValue(context, instanceId)); + } + + + void LuaJobManager::Lock::Connect(size_t operation1, + size_t operation2) + { + assert(jobLock_.get() != NULL); + jobLock_->Connect(operation1, operation2); } }