]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1964] protect critical_section_count_ in MultiThreadingMgr
authorRazvan Becheriu <razvan@isc.org>
Mon, 5 Jul 2021 08:22:16 +0000 (11:22 +0300)
committerRazvan Becheriu <razvan@isc.org>
Mon, 26 Jul 2021 09:28:08 +0000 (12:28 +0300)
src/lib/util/multi_threading_mgr.cc
src/lib/util/multi_threading_mgr.h

index 4b2c2d3df7ffa122e7a533c7a4d35ccda99cd827..b077d55ec2f2a8d20976c652b76d78b6a787d0ed 100644 (file)
@@ -36,12 +36,14 @@ MultiThreadingMgr::setMode(bool enabled) {
 
 void
 MultiThreadingMgr::enterCriticalSection() {
+    std::lock_guard<std::mutex> lk(mutex_);
     stopProcessing();
     ++critical_section_count_;
 }
 
 void
 MultiThreadingMgr::exitCriticalSection() {
+    std::lock_guard<std::mutex> lk(mutex_);
     if (critical_section_count_ == 0) {
         isc_throw(InvalidOperation, "invalid negative value for override");
     }
@@ -51,6 +53,12 @@ MultiThreadingMgr::exitCriticalSection() {
 
 bool
 MultiThreadingMgr::isInCriticalSection() {
+    std::lock_guard<std::mutex> lk(mutex_);
+    return (isInCriticalSectionInternal());
+}
+
+bool
+MultiThreadingMgr::isInCriticalSectionInternal() {
     return (critical_section_count_ != 0);
 }
 
@@ -120,7 +128,7 @@ MultiThreadingMgr::apply(bool enabled, uint32_t thread_count, uint32_t queue_siz
 
 void
 MultiThreadingMgr::stopProcessing() {
-    if (getMode() && !isInCriticalSection()) {
+    if (getMode() && !isInCriticalSectionInternal()) {
         if (getThreadPoolSize()) {
             thread_pool_.stop();
         }
@@ -139,7 +147,7 @@ MultiThreadingMgr::stopProcessing() {
 
 void
 MultiThreadingMgr::startProcessing() {
-    if (getMode() && !isInCriticalSection()) {
+    if (getMode() && !isInCriticalSectionInternal()) {
         if (getThreadPoolSize()) {
             thread_pool_.start(getThreadPoolSize());
         }
index 2fe8e50790b676cc9a1e010bc85f3d7b7a2775d7..6c9613fa691956f227b4bee7ccfd8fa22e51f271 100644 (file)
@@ -194,6 +194,10 @@ public:
 
     /// @brief Apply the multi-threading related settings.
     ///
+    /// This function should usually be called after constructing a
+    /// @ref MultiThreadingCriticalSection so that all thread pool parameters
+    /// can be safely applied.
+    ///
     /// @param enabled The enabled flag: true if multi-threading is enabled,
     /// false otherwise.
     /// @param thread_count The desired number of threads: non 0 if explicitly
@@ -238,6 +242,13 @@ protected:
 
 private:
 
+    /// @brief Is in critical section flag.
+    ///
+    /// Should be called in a thread safe context.
+    ///
+    /// @return The critical section flag.
+    bool isInCriticalSectionInternal();
+
     /// @brief Class method stops non-critical processing.
     ///
     /// Stops the DHCP thread pool if it's running and invokes
@@ -282,6 +293,9 @@ private:
 
     /// @brief List of CriticalSection entry and exit callback pairs.
     CSCallbackPairList cs_callbacks_;
+
+    /// @brief Mutex to protect the internal state.
+    std::mutex mutex_;
 };
 
 /// @note: everything here MUST be used ONLY from the main thread.