Avoid dead-lock with config packages and active stages

This commit is contained in:
Michael Friedrich 2019-05-08 16:06:46 +02:00
parent 736e0806d7
commit 704aabcb63
5 changed files with 21 additions and 9 deletions

View File

@ -85,7 +85,8 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full
const String& config, const Array::Ptr& errors, const Array::Ptr& diagnosticInformation)
{
{
boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex());
boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticPackageMutex());
if (!ConfigPackageUtility::PackageExists("_api")) {
ConfigPackageUtility::CreatePackage("_api");

View File

@ -63,7 +63,8 @@ void ConfigPackagesHandler::HandleGet(
ArrayData results;
{
boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex());
boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticPackageMutex());
for (const String& package : packages) {
results.emplace_back(new Dictionary({
{ "name", package },
@ -104,7 +105,8 @@ void ConfigPackagesHandler::HandlePost(
}
try {
boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex());
boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticPackageMutex());
ConfigPackageUtility::CreatePackage(packageName);
} catch (const std::exception& ex) {
HttpUtility::SendJsonError(response, params, 500, "Could not create package '" + packageName + "'.",

View File

@ -186,7 +186,8 @@ void ConfigPackageUtility::TryActivateStageCallback(const ProcessResult& pr, con
/* validation went fine, activate stage and reload */
if (pr.ExitStatus == 0) {
{
boost::mutex::scoped_lock lock(GetStaticMutex());
boost::mutex::scoped_lock lock(GetStaticPackageMutex());
ActivateStage(packageName, stageName);
}
@ -251,7 +252,7 @@ std::vector<String> ConfigPackageUtility::GetStages(const String& packageName)
String ConfigPackageUtility::GetActiveStageFromFile(const String& packageName)
{
/* Lock the transaction, reading this only happens on startup or when something really is broken. */
boost::mutex::scoped_lock lock(GetStaticMutex());
boost::mutex::scoped_lock lock(GetStaticActiveStageMutex());
String path = GetPackageDir() + "/" + packageName + "/active-stage";
@ -271,7 +272,7 @@ String ConfigPackageUtility::GetActiveStageFromFile(const String& packageName)
void ConfigPackageUtility::SetActiveStageToFile(const String& packageName, const String& stageName)
{
boost::mutex::scoped_lock lock(GetStaticMutex());
boost::mutex::scoped_lock lock(GetStaticActiveStageMutex());
String activeStagePath = GetPackageDir() + "/" + packageName + "/active-stage";
@ -380,7 +381,13 @@ bool ConfigPackageUtility::ValidateName(const String& name)
return (!boost::regex_search(name.GetData(), what, expr));
}
boost::mutex& ConfigPackageUtility::GetStaticMutex()
boost::mutex& ConfigPackageUtility::GetStaticPackageMutex()
{
static boost::mutex mutex;
return mutex;
}
boost::mutex& ConfigPackageUtility::GetStaticActiveStageMutex()
{
static boost::mutex mutex;
return mutex;

View File

@ -44,7 +44,8 @@ public:
static bool ContainsDotDot(const String& path);
static bool ValidateName(const String& name);
static boost::mutex& GetStaticMutex();
static boost::mutex& GetStaticPackageMutex();
static boost::mutex& GetStaticActiveStageMutex();
private:
static void CollectDirNames(const String& path, std::vector<String>& dirs);

View File

@ -120,7 +120,8 @@ void ConfigStagesHandler::HandlePost(
if (!files)
BOOST_THROW_EXCEPTION(std::invalid_argument("Parameter 'files' must be specified."));
boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex());
boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticPackageMutex());
stageName = ConfigPackageUtility::CreateStage(packageName, files);
/* validate the config. on success, activate stage and reload */