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);
-