]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
fixed rebase new-multi-threading-pkt-processing
authorRazvan Becheriu <razvan@isc.org>
Wed, 6 Nov 2019 17:20:51 +0000 (19:20 +0200)
committerRazvan Becheriu <razvan@isc.org>
Wed, 6 Nov 2019 17:32:52 +0000 (19:32 +0200)
src/lib/util/tests/thread_resource_unittest.cc
src/lib/util/thread_resource.h

index 9ce1c122a556c884051d557ec50dc639bff43e9f..4977ced90e3ba05bdda22ef084345167a1d6a2a7 100644 (file)
@@ -37,8 +37,7 @@ public:
         Resource::count_++;
         // increase the total number of instances ever created
         Resource::created_count_++;
-        // check that this instance in new and should not be found in the
-        // verification set
+        // check that this instance is not found in the verification set
         EXPECT_TRUE(Resource::set_.find(&data_) == Resource::set_.end());
         // add this instance to the verification set
         Resource::set_.emplace(&data_);
@@ -107,7 +106,7 @@ private:
     /// @brief mutex used to keep the internal state consistent
     static std::mutex mutex_;
 
-    /// @brief set to fold
+    /// @brief set to hold the distinct identification data of each instance
     static std::set<T*> set_;
 };
 
@@ -133,14 +132,29 @@ public:
     ~ThreadResourceTest() {
     }
 
+    /// @brief flag which indicates if main thread should wait for the test
+    /// thread to start
+    ///
+    /// @return the wait flag
+    bool waitThread() {
+        return wait_thread_;
+    }
+
     /// @brief flag which indicates if working thread should wait for main
     /// thread signal
     ///
     /// @return the wait flag
-    bool wait() {
+    bool waitMain() {
         return wait_;
     }
 
+    /// @brief block main thread until testing thread has processed the task
+    void wait() {
+        unique_lock<mutex> lck(mutex_);
+        // wait for the testing thread to process
+        cv_.wait(lck, [&]{ return (waitThread() == false); });
+    }
+
     /// @brief function used by main thread to unblock processing threads
     void signalThreads() {
         lock_guard<mutex> lk(wait_mutex_);
@@ -160,9 +174,15 @@ public:
         get<T>() = make_shared<ThreadResource<Resource<T>>>();
         // perform sanity checks
         sanityCheck<T>();
+        // reset the wait flag
         wait_ = true;
     }
 
+    /// @brief reset wait thread flag
+    void resetWaitThread() {
+        wait_thread_ = true;
+    }
+
     /// @brief check statistics
     ///
     /// @param expected_count check equality of this value with the number of
@@ -217,14 +237,39 @@ public:
         // sequential requests for the same resource
         checkInstances<T>(expected_count, expected_created, expected_destroyed);
 
+        {
+            // make sure this thread has started
+            lock_guard<mutex> lk(mutex_);
+            // reset wait thread flag
+            wait_thread_ = false;
+            // wake main thread if it is waiting for this thread to process
+            cv_.notify_all();
+        }
+
         if (signal) {
             unique_lock<std::mutex> lk(wait_mutex_);
             // if specified, wait for signal from main thread
-            wait_cv_.wait(lk, [&]{ return (wait() == false); });
+            wait_cv_.wait(lk, [&]{ return (waitMain() == false); });
         }
     }
 
 private:
+    /// @brief sanity check that the number of created instances is equal to the
+    /// number of destroyed instances
+    template <typename T>
+    void sanityCheck() {
+        // the number of created instances should match the number of destroyed
+        // instances
+        ASSERT_EQ(Resource<T>::createdCount(), Resource<T>::destroyedCount());
+    }
+
+    /// @brief mutex used to keep the internal state consistent
+    std::mutex mutex_;
+
+    /// @brief condition variable used to signal main thread that test thread
+    /// has started processing
+    condition_variable cv_;
+
     /// @brief mutex used to keep the internal state consistent
     /// related to the control of the main thread over the working threads exit
     std::mutex wait_mutex_;
@@ -232,6 +277,10 @@ private:
     /// @brief condition variable used to signal working threads to exit
     condition_variable wait_cv_;
 
+    /// @brief flag which indicates if main thread should wait for test thread
+    /// to start
+    bool wait_thread_;
+
     /// @brief flag which indicates if working thread should wait for main
     /// thread signal
     bool wait_;
@@ -251,6 +300,8 @@ TEST_F(ThreadResourceTest, testThreadResources) {
     reset<uint32_t>();
     // call run function on main thread and verify statistics
     run<uint32_t>(1, 1, 0);
+    // configure wait for test thread
+    resetWaitThread();
     // call run on a different thread and verify statistics
     threads.push_back(std::make_shared<std::thread>(std::bind(
         &ThreadResourceTest::run<uint32_t>, this, 2, 2, 0, true)));
@@ -280,6 +331,8 @@ TEST_F(ThreadResourceTest, testThreadResources) {
     reset<bool>();
     // call run function on main thread and verify statistics
     run<bool>(1, 1, 0);
+    // configure wait for test thread
+    resetWaitThread();
     // call run on a different thread and verify statistics
     threads.push_back(std::make_shared<std::thread>(std::bind(
         &ThreadResourceTest::run<bool>, this, 2, 2, 0, true)));
index bd360cbc7cb0c99b282ba8bcb2b89ae71d4f297b..9a8e44a6049f15e6e62af514e96deb6237580760 100644 (file)
@@ -4,8 +4,8 @@
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef THREAD_RESOURCE_MGR_H
-#define THREAD_RESOURCE_MGR_H
+#ifndef THREAD_RESOURCE_H
+#define THREAD_RESOURCE_H
 
 #include <boost/shared_ptr.hpp>
 #include <mutex>
@@ -46,4 +46,4 @@ private:
 }  // namespace dhcp
 }  // namespace isc
 
-#endif  // THREAD_RESOURCE_MGR_H
+#endif  // THREAD_RESOURCE_H