]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
thread save StatsMgr
authorRazvan Becheriu <razvan@isc.org>
Tue, 26 Mar 2019 05:45:30 +0000 (07:45 +0200)
committerRazvan Becheriu <razvan@isc.org>
Fri, 12 Apr 2019 12:10:40 +0000 (15:10 +0300)
src/lib/dhcpsrv/srv_config.cc
src/lib/stats/stats_mgr.cc
src/lib/stats/stats_mgr.h

index a4d3b59a61d661f93c05ab3e714fd70a285f26da..5a4754d70bfeaea25e6fe9bbf476459254d4f80a 100644 (file)
@@ -38,6 +38,8 @@ SrvConfig::SrvConfig()
       cfg_host_operations6_(CfgHostOperations::createConfig6()),
       class_dictionary_(new ClientClassDictionary()),
       decline_timer_(0), echo_v4_client_id_(true), dhcp4o6_port_(0),
+      server_threads_(0),
+      server_max_thread_queue_size_(0),
       d2_client_config_(new D2ClientConfig()),
       configured_globals_(Element::createMap()),
       cfg_consist_(new CfgConsistency()) {
@@ -56,6 +58,8 @@ SrvConfig::SrvConfig(const uint32_t sequence)
       cfg_host_operations6_(CfgHostOperations::createConfig6()),
       class_dictionary_(new ClientClassDictionary()),
       decline_timer_(0), echo_v4_client_id_(true), dhcp4o6_port_(0),
+      server_threads_(0),
+      server_max_thread_queue_size_(0),
       d2_client_config_(new D2ClientConfig()),
       configured_globals_(Element::createMap()),
       cfg_consist_(new CfgConsistency()) {
@@ -250,7 +254,6 @@ SrvConfig::mergeGlobals(SrvConfig& other) {
 
 void
 SrvConfig::removeStatistics() {
-
     // Removes statistics for v4 and v6 subnets
     getCfgSubnets4()->removeStatistics();
 
index e5b29cb5eb70792604953ef8c4be1673926c402b..41f2bcbca9a90401ba6319d310fa4c5ab15cb4c9 100644 (file)
@@ -30,61 +30,107 @@ StatsMgr::StatsMgr()
     mutex_.reset(new std::mutex());
 }
 
-void StatsMgr::setValue(const std::string& name, const int64_t value) {
-    LockGuard<std::mutex> lock(mutex_.get());
+void StatsMgr::setValue(const std::string& name, const int64_t value, bool lock) {
+    std::mutex* mlock = nullptr;
+    if (lock) {
+        mlock = mutex_.get();
+    }
+    LockGuard<std::mutex> lockGuard(mlock);
     setValueInternal(name, value);
 }
 
-void StatsMgr::setValue(const std::string& name, const double value) {
-    LockGuard<std::mutex> lock(mutex_.get());
+void StatsMgr::setValue(const std::string& name, const double value, bool lock) {
+    std::mutex* mlock = nullptr;
+    if (lock) {
+        mlock = mutex_.get();
+    }
+    LockGuard<std::mutex> lockGuard(mlock);
     setValueInternal(name, value);
 }
 
-void StatsMgr::setValue(const std::string& name, const StatsDuration& value) {
-    LockGuard<std::mutex> lock(mutex_.get());
+void StatsMgr::setValue(const std::string& name, const StatsDuration& value, bool lock) {
+    std::mutex* mlock = nullptr;
+    if (lock) {
+        mlock = mutex_.get();
+    }
+    LockGuard<std::mutex> lockGuard(mlock);
     setValueInternal(name, value);
 }
-void StatsMgr::setValue(const std::string& name, const std::string& value) {
-    LockGuard<std::mutex> lock(mutex_.get());
+
+void StatsMgr::setValue(const std::string& name, const std::string& value, bool lock) {
+    std::mutex* mlock = nullptr;
+    if (lock) {
+        mlock = mutex_.get();
+    }
+    LockGuard<std::mutex> lockGuard(mlock);
     setValueInternal(name, value);
 }
 
-void StatsMgr::addValue(const std::string& name, const int64_t value) {
-    LockGuard<std::mutex> lock(mutex_.get());
+void StatsMgr::addValue(const std::string& name, const int64_t value, bool lock) {
+    std::mutex* mlock = nullptr;
+    if (lock) {
+        mlock = mutex_.get();
+    }
+    LockGuard<std::mutex> lockGuard(mlock);
     addValueInternal(name, value);
 }
 
-void StatsMgr::addValue(const std::string& name, const double value) {
-    LockGuard<std::mutex> lock(mutex_.get());
+void StatsMgr::addValue(const std::string& name, const double value, bool lock) {
+    std::mutex* mlock = nullptr;
+    if (lock) {
+        mlock = mutex_.get();
+    }
+    LockGuard<std::mutex> lockGuard(mlock);
     addValueInternal(name, value);
 }
 
-void StatsMgr::addValue(const std::string& name, const StatsDuration& value) {
-    LockGuard<std::mutex> lock(mutex_.get());
+void StatsMgr::addValue(const std::string& name, const StatsDuration& value, bool lock) {
+    std::mutex* mlock = nullptr;
+    if (lock) {
+        mlock = mutex_.get();
+    }
+    LockGuard<std::mutex> lockGuard(mlock);
     addValueInternal(name, value);
 }
 
-void StatsMgr::addValue(const std::string& name, const std::string& value) {
-    LockGuard<std::mutex> lock(mutex_.get());
+void StatsMgr::addValue(const std::string& name, const std::string& value, bool lock) {
+    std::mutex* mlock = nullptr;
+    if (lock) {
+        mlock = mutex_.get();
+    }
+    LockGuard<std::mutex> lockGuard(mlock);
     addValueInternal(name, value);
 }
 
-ObservationPtr StatsMgr::getObservation(const std::string& name) const {
-    LockGuard<std::mutex> lock(mutex_.get());
+ObservationPtr StatsMgr::getObservation(const std::string& name, bool lock) const {
+    std::mutex* mlock = nullptr;
+    if (lock) {
+        mlock = mutex_.get();
+    }
+    LockGuard<std::mutex> lockGuard(mlock);
     /// @todo: Implement contexts.
     // Currently we keep everything in a global context.
     return (global_->get(name));
+
 }
 
-void StatsMgr::addObservation(const ObservationPtr& stat) {
-    LockGuard<std::mutex> lock(mutex_.get());
+void StatsMgr::addObservation(const ObservationPtr& stat, bool lock) {
+    std::mutex* mlock = nullptr;
+    if (lock) {
+        mlock = mutex_.get();
+    }
+    LockGuard<std::mutex> lockGuard(mlock);
     /// @todo: Implement contexts.
     // Currently we keep everything in a global context.
     return (global_->add(stat));
 }
 
-bool StatsMgr::deleteObservation(const std::string& name) {
-    LockGuard<std::mutex> lock(mutex_.get());
+bool StatsMgr::deleteObservation(const std::string& name, bool lock) {
+    std::mutex* mlock = nullptr;
+    if (lock) {
+        mlock = mutex_.get();
+    }
+    LockGuard<std::mutex> lockGuard(mlock);
     /// @todo: Implement contexts.
     // Currently we keep everything in a global context.
     return (global_->del(name));
@@ -102,7 +148,8 @@ void StatsMgr::setMaxSampleCount(const std::string& , uint32_t){
 }
 
 bool StatsMgr::reset(const std::string& name) {
-    ObservationPtr obs = getObservation(name);
+    LockGuard<std::mutex> lock(mutex_.get());
+    ObservationPtr obs = getObservation(name, false);
     if (obs) {
         obs->reset();
         return (true);
@@ -122,8 +169,9 @@ void StatsMgr::removeAll() {
 }
 
 isc::data::ConstElementPtr StatsMgr::get(const std::string& name) const {
+    LockGuard<std::mutex> lock(mutex_.get());
     isc::data::ElementPtr response = isc::data::Element::createMap(); // a map
-    ObservationPtr obs = getObservation(name);
+    ObservationPtr obs = getObservation(name, false);
     if (obs) {
         response->set(name, obs->getJSON()); // that contains the observation
     }
index 123de1f76cac35c9bac28b9fc4cdb6571e5591e2..d9052b8426f02efd53d6c7dddf9fc7bffd9b7bee 100644 (file)
@@ -77,56 +77,56 @@ class StatsMgr : public boost::noncopyable {
     /// @param name name of the observation
     /// @param value integer value observed
     /// @throw InvalidStatType if statistic is not integer
-    void setValue(const std::string& name, const int64_t value);
+    void setValue(const std::string& name, const int64_t value, bool lock = true);
 
     /// @brief Records absolute floating point observation.
     ///
     /// @param name name of the observation
     /// @param value floating point value observed
     /// @throw InvalidStatType if statistic is not fp
-    void setValue(const std::string& name, const double value);
+    void setValue(const std::string& name, const double value, bool lock = true);
 
     /// @brief Records absolute duration observation.
     ///
     /// @param name name of the observation
     /// @param value duration value observed
     /// @throw InvalidStatType if statistic is not time duration
-    void setValue(const std::string& name, const StatsDuration& value);
+    void setValue(const std::string& name, const StatsDuration& value, bool lock = true);
 
     /// @brief Records absolute string observation.
     ///
     /// @param name name of the observation
     /// @param value string value observed
     /// @throw InvalidStatType if statistic is not a string
-    void setValue(const std::string& name, const std::string& value);
+    void setValue(const std::string& name, const std::string& value, bool lock = true);
 
     /// @brief Records incremental integer observation.
     ///
     /// @param name name of the observation
     /// @param value integer value observed
     /// @throw InvalidStatType if statistic is not integer
-    void addValue(const std::string& name, const int64_t value);
+    void addValue(const std::string& name, const int64_t value, bool lock = true);
 
     /// @brief Records incremental floating point observation.
     ///
     /// @param name name of the observation
     /// @param value floating point value observed
     /// @throw InvalidStatType if statistic is not fp
-    void addValue(const std::string& name, const double value);
+    void addValue(const std::string& name, const double value, bool lock = true);
 
     /// @brief Records incremental duration observation.
     ///
     /// @param name name of the observation
     /// @param value duration value observed
     /// @throw InvalidStatType if statistic is not time duration
-    void addValue(const std::string& name, const StatsDuration& value);
+    void addValue(const std::string& name, const StatsDuration& value, bool lock = true);
 
     /// @brief Records incremental string observation.
     ///
     /// @param name name of the observation
     /// @param value string value observed
     /// @throw InvalidStatType if statistic is not a string
-    void addValue(const std::string& name, const std::string& value);
+    void addValue(const std::string& name, const std::string& value, bool lock = true);
 
     /// @brief Determines maximum age of samples.
     ///
@@ -207,7 +207,7 @@ class StatsMgr : public boost::noncopyable {
     /// Used in testing only. Production code should use @ref get() method.
     /// @param name name of the statistic
     /// @return Pointer to the Observation object
-    ObservationPtr getObservation(const std::string& name) const;
+    ObservationPtr getObservation(const std::string& name, bool lock = true) const;
 
     /// @brief Generates statistic name in a given context
     ///
@@ -350,14 +350,13 @@ private:
     /// @throw InvalidStatType is statistic exists and has a different type.
     template<typename DataType>
     void setValueInternal(const std::string& name, DataType value) {
-
         // If we want to log each observation, here would be the best place for it.
-        ObservationPtr stat = getObservation(name);
+        ObservationPtr stat = getObservation(name, false);
         if (stat) {
             stat->setValue(value);
         } else {
             stat.reset(new Observation(name, value));
-            addObservation(stat);
+            addObservation(stat, false);
         }
     }
 
@@ -375,14 +374,13 @@ private:
     /// @throw InvalidStatType is statistic exists and has a different type.
     template<typename DataType>
     void addValueInternal(const std::string& name, DataType value) {
-
         // If we want to log each observation, here would be the best place for it.
-        ObservationPtr existing = getObservation(name);
+        ObservationPtr existing = getObservation(name, false);
         if (!existing) {
             // We tried to add to a non-existing statistic. We can recover from
             // that. Simply add the new incremental value as a new statistic and
             // we're done.
-            setValue(name, value);
+            setValue(name, value, false);
             return;
         } else {
             // Let's hope it is of correct type. If not, the underlying
@@ -398,7 +396,7 @@ private:
     /// That's an utility method used by public @ref setValue() and
     /// @ref addValue() methods.
     /// @param stat observation
-    void addObservation(const ObservationPtr& stat);
+    void addObservation(const ObservationPtr& stat, bool lock = true);
 
     /// @private
 
@@ -406,7 +404,7 @@ private:
     ///
     /// @param name of the statistic to be deleted
     /// @return true if deleted, false if not found
-    bool deleteObservation(const std::string& name);
+    bool deleteObservation(const std::string& name, bool lock = true);
 
     /// @brief Utility method that attempts to extract statistic name
     ///