This is an automated email from the ASF dual-hosted git repository.

swebb2066 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git


The following commit(s) were added to refs/heads/master by this push:
     new 9775ae5c ThreadUtility: restart periodic worker after queue becomes 
empty (#692)
9775ae5c is described below

commit 9775ae5c4d8f2f7aa8d0bd509f0142177ef9ebc2
Author: jmestwa-coder <[email protected]>
AuthorDate: Sat May 30 12:16:55 2026 +0530

    ThreadUtility: restart periodic worker after queue becomes empty (#692)
---
 src/main/cpp/threadutility.cpp                 |  3 ++
 src/test/cpp/helpers/threadutilitytestcase.cpp | 43 +++++++++++++++++++++++++-
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/src/main/cpp/threadutility.cpp b/src/main/cpp/threadutility.cpp
index 70476af5..8b83f352 100644
--- a/src/main/cpp/threadutility.cpp
+++ b/src/main/cpp/threadutility.cpp
@@ -400,7 +400,10 @@ void ThreadUtility::priv_data::doPeriodicTasks()
                                break;
                        this->jobs.erase(pItem);
                        if (this->jobs.empty())
+                       {
+                               this->threadIsActive = false;
                                return;
+                       }
                }
 
                std::unique_lock<std::mutex> lock(this->interrupt_mutex);
diff --git a/src/test/cpp/helpers/threadutilitytestcase.cpp 
b/src/test/cpp/helpers/threadutilitytestcase.cpp
index c62d665b..8c10fecb 100644
--- a/src/test/cpp/helpers/threadutilitytestcase.cpp
+++ b/src/test/cpp/helpers/threadutilitytestcase.cpp
@@ -22,6 +22,8 @@
 #include <log4cxx/patternlayout.h>
 #include <log4cxx/fileappender.h>
 #include <log4cxx/logmanager.h>
+#include <atomic>
+#include <chrono>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
@@ -33,6 +35,7 @@ LOGUNIT_CLASS(ThreadUtilityTest)
        LOGUNIT_TEST(testNullFunctions);
        LOGUNIT_TEST(testCustomFunctions);
        LOGUNIT_TEST(testDefaultFunctions);
+       LOGUNIT_TEST(testPeriodicTaskRestartsAfterEmptyQueue);
 #if LOG4CXX_HAS_PTHREAD_SETNAME || defined(_WIN32)
        LOGUNIT_TEST(testThreadNameLogging);
 #endif
@@ -107,6 +110,45 @@ public:
                t.join();
        }
 
+       void testPeriodicTaskRestartsAfterEmptyQueue()
+       {
+               auto thrUtil = ThreadUtility::instance();
+               const LogString 
firstTask(LOG4CXX_STR("ThreadUtilityTest.first"));
+               const LogString 
secondTask(LOG4CXX_STR("ThreadUtilityTest.second"));
+               std::atomic<int> firstRuns{0};
+               std::atomic<int> secondRuns{0};
+
+               thrUtil->removeAllPeriodicTasks();
+               thrUtil->addPeriodicTask(firstTask, [thrUtil, firstTask, 
&firstRuns]() {
+                       ++firstRuns;
+                       thrUtil->removePeriodicTask(firstTask);
+               }, std::chrono::milliseconds(1));
+
+               for (int i = 0; i < 100 && firstRuns.load() == 0; ++i)
+               {
+                       
std::this_thread::sleep_for(std::chrono::milliseconds(10));
+               }
+               LOGUNIT_ASSERT_EQUAL(1, firstRuns.load());
+
+               for (int i = 0; i < 100 && thrUtil->hasPeriodicTask(firstTask); 
++i)
+               {
+                       
std::this_thread::sleep_for(std::chrono::milliseconds(10));
+               }
+               LOGUNIT_ASSERT(!thrUtil->hasPeriodicTask(firstTask));
+               std::this_thread::sleep_for(std::chrono::milliseconds(50));
+
+               thrUtil->addPeriodicTask(secondTask, [&secondRuns]() {
+                       ++secondRuns;
+               }, std::chrono::milliseconds(1));
+
+               for (int i = 0; i < 100 && secondRuns.load() == 0; ++i)
+               {
+                       
std::this_thread::sleep_for(std::chrono::milliseconds(10));
+               }
+               thrUtil->removePeriodicTask(secondTask);
+               LOGUNIT_ASSERT(0 < secondRuns.load());
+       }
+
        void testThreadNameLogging()
        {
                auto layout = std::make_shared<PatternLayout>(LOG4CXX_STR("%T 
%m%n"));
@@ -124,4 +166,3 @@ public:
 
 
 LOGUNIT_TEST_SUITE_REGISTRATION(ThreadUtilityTest);
-

Reply via email to