summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kutsan (GitHub) <akutsan@luxoft.com>2020-06-23 00:57:06 +0300
committerGitHub <noreply@github.com>2020-06-22 17:57:06 -0400
commit67b92faf0c03d5186014e346b4f607cedc3f47f2 (patch)
treee15fa1cb1639a20af94e1566bce1f4207fa501b3
parentdebe7f40ccccfe3f2d84ec94a6fee10a9988796b (diff)
downloadsdl_core-67b92faf0c03d5186014e346b4f607cedc3f47f2.tar.gz
Fixes race condition in messagemeter.h (#3377)
SDLCORE-373 Unprotected critical section accessed by two different threads, timing_map was being modified by clearing the map identifiers causing a crash in boost::date_time Review: Change RWLock to Lock, Added FrequencyImpl private method Co-authored-by: Mario Godinez <mgodine6@ford.com>
-rw-r--r--src/components/include/utils/messagemeter.h25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/components/include/utils/messagemeter.h b/src/components/include/utils/messagemeter.h
index 1148a65b57..fb70839640 100644
--- a/src/components/include/utils/messagemeter.h
+++ b/src/components/include/utils/messagemeter.h
@@ -37,8 +37,11 @@
#include <map>
#include <set>
#include "utils/date_time.h"
+#include "utils/lock.h"
namespace utils {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "MessageMeter")
/**
@brief The MessageMeter class need to count message frequency
Default time range value is 1 second
@@ -86,10 +89,13 @@ class MessageMeter {
date_time::TimeDuration time_range() const;
private:
+ size_t FrequencyImpl(const Id& id);
+
date_time::TimeDuration time_range_;
typedef std::multiset<date_time::TimeDuration> Timings;
typedef std::map<Id, Timings> TimingMap;
TimingMap timing_map_;
+ sync_primitives::Lock timing_map_lock_;
};
template <class Id>
@@ -99,22 +105,33 @@ MessageMeter<Id>::MessageMeter() {
template <class Id>
size_t MessageMeter<Id>::TrackMessage(const Id& id) {
+ LOG4CXX_AUTO_TRACE(logger_);
return TrackMessages(id, 1);
}
template <class Id>
size_t MessageMeter<Id>::TrackMessages(const Id& id, const size_t count) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(timing_map_lock_);
Timings& timings = timing_map_[id];
const date_time::TimeDuration current_time = date_time::getCurrentTime();
for (size_t i = 0; i < count; ++i) {
// Adding to the end is amortized constant
timings.insert(timings.end(), current_time);
}
- return Frequency(id);
+ return FrequencyImpl(id);
}
template <class Id>
size_t MessageMeter<Id>::Frequency(const Id& id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(timing_map_lock_);
+ return FrequencyImpl(id);
+}
+
+template <class Id>
+size_t MessageMeter<Id>::FrequencyImpl(const Id& id) {
+ LOG4CXX_AUTO_TRACE(logger_);
typename TimingMap::iterator it = timing_map_.find(id);
if (it == timing_map_.end()) {
return 0u;
@@ -131,21 +148,27 @@ size_t MessageMeter<Id>::Frequency(const Id& id) {
template <class Id>
void MessageMeter<Id>::RemoveIdentifier(const Id& id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(timing_map_lock_);
timing_map_.erase(id);
}
template <class Id>
void MessageMeter<Id>::ClearIdentifiers() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(timing_map_lock_);
timing_map_.clear();
}
template <class Id>
void MessageMeter<Id>::set_time_range(const size_t time_range_msecs) {
+ LOG4CXX_AUTO_TRACE(logger_);
time_range_ = date_time::milliseconds(time_range_msecs);
}
template <class Id>
void MessageMeter<Id>::set_time_range(
const date_time::TimeDuration& time_range) {
+ LOG4CXX_AUTO_TRACE(logger_);
time_range_ = time_range;
}
template <class Id>