From ef5013b9038b07afc228122bade44dac52396a46 Mon Sep 17 00:00:00 2001 From: Jean Flach Date: Wed, 20 Sep 2017 16:40:02 +0200 Subject: [PATCH] Use locks in api config staging refs #3668 --- lib/remote/configobjectutility.cpp | 12 +++++++----- lib/remote/configpackageshandler.cpp | 16 ++++++++++------ lib/remote/configpackageutility.cpp | 10 +++++++++- lib/remote/configpackageutility.hpp | 2 ++ lib/remote/configstageshandler.cpp | 1 + 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/remote/configobjectutility.cpp b/lib/remote/configobjectutility.cpp index 77c2fb895..09344a4f9 100644 --- a/lib/remote/configobjectutility.cpp +++ b/lib/remote/configobjectutility.cpp @@ -102,11 +102,14 @@ String ConfigObjectUtility::CreateObjectConfig(const Type::Ptr& type, const Stri bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& fullName, const String& config, const Array::Ptr& errors) { - if (!ConfigPackageUtility::PackageExists("_api")) { - ConfigPackageUtility::CreatePackage("_api"); + { + boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex()); + if (!ConfigPackageUtility::PackageExists("_api")) { + ConfigPackageUtility::CreatePackage("_api"); - String stage = ConfigPackageUtility::CreateStage("_api"); - ConfigPackageUtility::ActivateStage("_api", stage); + String stage = ConfigPackageUtility::CreateStage("_api"); + ConfigPackageUtility::ActivateStage("_api", stage); + } } String path = GetObjectConfigPath(type, fullName); @@ -240,4 +243,3 @@ bool ConfigObjectUtility::DeleteObject(const ConfigObject::Ptr& object, bool cas return DeleteObjectHelper(object, cascade, errors); } - diff --git a/lib/remote/configpackageshandler.cpp b/lib/remote/configpackageshandler.cpp index 2fb00f7f7..0b41cd65b 100644 --- a/lib/remote/configpackageshandler.cpp +++ b/lib/remote/configpackageshandler.cpp @@ -53,12 +53,15 @@ void ConfigPackagesHandler::HandleGet(const ApiUser::Ptr& user, HttpRequest& req Array::Ptr results = new Array(); - for (const String& package : packages) { - Dictionary::Ptr packageInfo = new Dictionary(); - packageInfo->Set("name", package); - packageInfo->Set("stages", Array::FromVector(ConfigPackageUtility::GetStages(package))); - packageInfo->Set("active-stage", ConfigPackageUtility::GetActiveStage(package)); - results->Add(packageInfo); + { + boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex()); + for (const String& package : packages) { + Dictionary::Ptr packageInfo = new Dictionary(); + packageInfo->Set("name", package); + packageInfo->Set("stages", Array::FromVector(ConfigPackageUtility::GetStages(package))); + packageInfo->Set("active-stage", ConfigPackageUtility::GetActiveStage(package)); + results->Add(packageInfo); + } } Dictionary::Ptr result = new Dictionary(); @@ -85,6 +88,7 @@ void ConfigPackagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& re Dictionary::Ptr result1 = new Dictionary(); try { + boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex()); ConfigPackageUtility::CreatePackage(packageName); } catch (const std::exception& ex) { HttpUtility::SendJsonError(response, 500, "Could not create package.", diff --git a/lib/remote/configpackageutility.cpp b/lib/remote/configpackageutility.cpp index 024b01a2c..b7f04a18f 100644 --- a/lib/remote/configpackageutility.cpp +++ b/lib/remote/configpackageutility.cpp @@ -190,7 +190,10 @@ void ConfigPackageUtility::TryActivateStageCallback(const ProcessResult& pr, con /* validation went fine, activate stage and reload */ if (pr.ExitStatus == 0) { - ActivateStage(packageName, stageName); + { + boost::mutex::scoped_lock lock(GetStaticMutex()); + ActivateStage(packageName, stageName); + } if (reload) Application::RequestRestart(); @@ -317,3 +320,8 @@ bool ConfigPackageUtility::ValidateName(const String& name) return (!boost::regex_search(name.GetData(), what, expr)); } +boost::mutex& ConfigPackageUtility::GetStaticMutex(void) +{ + static boost::mutex mutex; + return mutex; +} diff --git a/lib/remote/configpackageutility.hpp b/lib/remote/configpackageutility.hpp index 80813879d..a06eb33f7 100644 --- a/lib/remote/configpackageutility.hpp +++ b/lib/remote/configpackageutility.hpp @@ -58,6 +58,8 @@ public: static bool ContainsDotDot(const String& path); static bool ValidateName(const String& name); + static boost::mutex& GetStaticMutex(void); + private: static void CollectDirNames(const String& path, std::vector& dirs); static void CollectPaths(const String& path, std::vector >& paths); diff --git a/lib/remote/configstageshandler.cpp b/lib/remote/configstageshandler.cpp index fa1e3309f..dc1d0ce08 100644 --- a/lib/remote/configstageshandler.cpp +++ b/lib/remote/configstageshandler.cpp @@ -110,6 +110,7 @@ void ConfigStagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& requ if (!files) BOOST_THROW_EXCEPTION(std::invalid_argument("Parameter 'files' must be specified.")); + boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex()); stageName = ConfigPackageUtility::CreateStage(packageName, files); /* validate the config. on success, activate stage and reload */ -- 2.40.0