[Fix #1971] Use recursive locks for config data predicates

This commit is contained in:
Teddy Reed 2016-03-26 21:52:22 -07:00
parent 684697ba8d
commit a18444813b

View File

@ -56,12 +56,17 @@ const std::string kExecutingQuery = "executing_query";
const std::string kFailedQueries = "failed_queries"; const std::string kFailedQueries = "failed_queries";
// The config may be accessed and updated asynchronously; use mutexes. // The config may be accessed and updated asynchronously; use mutexes.
Mutex config_schedule_mutex_;
Mutex config_performance_mutex_;
Mutex config_files_mutex_;
Mutex config_hash_mutex_; Mutex config_hash_mutex_;
Mutex config_valid_mutex_; Mutex config_valid_mutex_;
using RecursiveMutex = std::recursive_mutex;
using RecursiveLock = std::lock_guard<std::recursive_mutex>;
/// Several config methods require enumeration via predicate lambdas.
RecursiveMutex config_schedule_mutex_;
RecursiveMutex config_files_mutex_;
RecursiveMutex config_performance_mutex_;
using PackRef = std::shared_ptr<Pack>; using PackRef = std::shared_ptr<Pack>;
/** /**
@ -218,7 +223,7 @@ Config::Config()
void Config::addPack(const std::string& name, void Config::addPack(const std::string& name,
const std::string& source, const std::string& source,
const pt::ptree& tree) { const pt::ptree& tree) {
WriteLock wlock(config_schedule_mutex_); RecursiveLock wlock(config_schedule_mutex_);
try { try {
schedule_->add(std::make_shared<Pack>(name, source, tree)); schedule_->add(std::make_shared<Pack>(name, source, tree));
if (schedule_->last()->shouldPackExecute()) { if (schedule_->last()->shouldPackExecute()) {
@ -230,19 +235,19 @@ void Config::addPack(const std::string& name,
} }
void Config::removePack(const std::string& pack) { void Config::removePack(const std::string& pack) {
WriteLock wlock(config_schedule_mutex_); RecursiveLock wlock(config_schedule_mutex_);
return schedule_->remove(pack); return schedule_->remove(pack);
} }
void Config::addFile(const std::string& source, void Config::addFile(const std::string& source,
const std::string& category, const std::string& category,
const std::string& path) { const std::string& path) {
WriteLock wlock(config_files_mutex_); RecursiveLock wlock(config_files_mutex_);
files_[source][category].push_back(path); files_[source][category].push_back(path);
} }
void Config::removeFiles(const std::string& source) { void Config::removeFiles(const std::string& source) {
WriteLock wlock(config_files_mutex_); RecursiveLock wlock(config_files_mutex_);
if (files_.count(source)) { if (files_.count(source)) {
FileCategories().swap(files_[source]); FileCategories().swap(files_[source]);
} }
@ -251,7 +256,7 @@ void Config::removeFiles(const std::string& source) {
void Config::scheduledQueries( void Config::scheduledQueries(
std::function<void(const std::string& name, const ScheduledQuery& query)> std::function<void(const std::string& name, const ScheduledQuery& query)>
predicate) { predicate) {
WriteLock lock(config_schedule_mutex_); RecursiveLock lock(config_schedule_mutex_);
for (const PackRef& pack : *schedule_) { for (const PackRef& pack : *schedule_) {
for (const auto& it : pack->getSchedule()) { for (const auto& it : pack->getSchedule()) {
std::string name = it.first; std::string name = it.first;
@ -279,7 +284,7 @@ void Config::scheduledQueries(
} }
void Config::packs(std::function<void(PackRef& pack)> predicate) { void Config::packs(std::function<void(PackRef& pack)> predicate) {
WriteLock lock(config_schedule_mutex_); RecursiveLock lock(config_schedule_mutex_);
for (PackRef& pack : schedule_->packs_) { for (PackRef& pack : schedule_->packs_) {
predicate(pack); predicate(pack);
} }
@ -532,7 +537,7 @@ void Config::purge() {
return false; return false;
}; };
WriteLock lock(config_schedule_mutex_); RecursiveLock lock(config_schedule_mutex_);
// Iterate over each result set in the database. // Iterate over each result set in the database.
for (const auto& saved_query : saved_queries) { for (const auto& saved_query : saved_queries) {
if (queryExists(saved_query)) { if (queryExists(saved_query)) {
@ -585,7 +590,7 @@ void Config::recordQueryPerformance(const std::string& name,
size_t size, size_t size,
const Row& r0, const Row& r0,
const Row& r1) { const Row& r1) {
WriteLock lock(config_performance_mutex_); RecursiveLock lock(config_performance_mutex_);
if (performance_.count(name) == 0) { if (performance_.count(name) == 0) {
performance_[name] = QueryPerformance(); performance_[name] = QueryPerformance();
} }
@ -643,7 +648,7 @@ void Config::getPerformanceStats(
const std::string& name, const std::string& name,
std::function<void(const QueryPerformance& query)> predicate) { std::function<void(const QueryPerformance& query)> predicate) {
if (performance_.count(name) > 0) { if (performance_.count(name) > 0) {
WriteLock lock(config_performance_mutex_); RecursiveLock lock(config_performance_mutex_);
predicate(performance_.at(name)); predicate(performance_.at(name));
} }
} }
@ -688,7 +693,7 @@ const std::shared_ptr<ConfigParserPlugin> Config::getParser(
void Config::files( void Config::files(
std::function<void(const std::string& category, std::function<void(const std::string& category,
const std::vector<std::string>& files)> predicate) { const std::vector<std::string>& files)> predicate) {
WriteLock lock(config_files_mutex_); RecursiveLock lock(config_files_mutex_);
for (const auto& it : files_) { for (const auto& it : files_) {
for (const auto& category : it.second) { for (const auto& category : it.second) {
predicate(category.first, category.second); predicate(category.first, category.second);