This is an automated email from the ASF dual-hosted git repository. swebb2066 pushed a commit to branch symplify_thread_utiltiy in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git
commit 1cb74b8130be0cd6898f2bd2c2f5d25760c9c986 Author: Stephen Webb <[email protected]> AuthorDate: Sun May 31 16:07:33 2026 +1000 Ensure a shared ThreadUtility flag change is visible --- src/main/cpp/threadutility.cpp | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/main/cpp/threadutility.cpp b/src/main/cpp/threadutility.cpp index 8b83f352..63195442 100644 --- a/src/main/cpp/threadutility.cpp +++ b/src/main/cpp/threadutility.cpp @@ -23,6 +23,7 @@ #include "log4cxx/helpers/loglog.h" #include "log4cxx/helpers/transcoder.h" +#include <atomic> #include <signal.h> #include <mutex> #include <list> @@ -79,22 +80,16 @@ struct ThreadUtility::priv_data std::thread thread; std::condition_variable interrupt; std::mutex interrupt_mutex; - bool terminated{ false }; + std::atomic<bool> terminated{ false }; int retryCount{ 2 }; Period maxDelay{ 0 }; - bool threadIsActive{ false }; + std::atomic<bool> threadIsActive{ false }; void doPeriodicTasks(); - void setTerminated() - { - std::lock_guard<std::mutex> lock(interrupt_mutex); - terminated = true; - } - void stopThread() { - setTerminated(); + terminated.store(true); interrupt.notify_all(); if (thread.joinable()) thread.join(); @@ -273,14 +268,18 @@ void ThreadUtility::addPeriodicTask(const LogString& name, std::function<void()> m_priv->jobs.push_back( priv_data::NamedPeriodicFunction{name, delay, currentTime + delay, f, 0, false} ); // Restart thread if it has stopped. - if (!m_priv->threadIsActive && m_priv->thread.joinable()) + if (!m_priv->threadIsActive.load() && m_priv->thread.joinable()) m_priv->thread.join(); if (!m_priv->thread.joinable()) { - m_priv->terminated = false; - m_priv->threadIsActive = true; - m_priv->thread = createThread(LOG4CXX_STR("log4cxx"), std::bind(&priv_data::doPeriodicTasks, m_priv.get())); + m_priv->terminated.store(false); + m_priv->thread = createThread(LOG4CXX_STR("log4cxx"), [this]() + { + m_priv->threadIsActive.store(true); + m_priv->doPeriodicTasks(); + m_priv->threadIsActive.store(false); + }); } else m_priv->interrupt.notify_one(); @@ -351,7 +350,7 @@ void ThreadUtility::removePeriodicTasksMatching(const LogString& namePrefix) // Run ready tasks void ThreadUtility::priv_data::doPeriodicTasks() { - while (!this->terminated) + while (!this->terminated.load()) { auto currentTime = std::chrono::system_clock::now(); TimePoint nextOperationTime = currentTime + this->maxDelay; @@ -359,7 +358,7 @@ void ThreadUtility::priv_data::doPeriodicTasks() std::lock_guard<std::recursive_mutex> lock(this->job_mutex); for (auto& item : this->jobs) { - if (this->terminated) + if (this->terminated.load()) return; if (item.removed) ; @@ -400,16 +399,12 @@ 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); this->interrupt.wait_until(lock, nextOperationTime); } - this->threadIsActive = false; } } //namespace helpers
