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 bf873fcd Improve asyncappender robustness (#403) bf873fcd is described below commit bf873fcda0d9d2213dce7cd95a3c9af66765b705 Author: Stephen Webb <stephen.w...@ieee.org> AuthorDate: Fri Jul 26 13:29:46 2024 +1000 Improve asyncappender robustness (#403) * The lock must be acquired before notify_all --- src/main/cpp/asyncappender.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/cpp/asyncappender.cpp b/src/main/cpp/asyncappender.cpp index 69533ff6..cd302f62 100644 --- a/src/main/cpp/asyncappender.cpp +++ b/src/main/cpp/asyncappender.cpp @@ -223,6 +223,11 @@ struct AsyncAppender::AsyncAppenderPriv : public AppenderSkeleton::AppenderSkele std::lock_guard<std::mutex> lock(this->bufferMutex); this->closed = true; } + + /** + * Used to ensure the dispatch thread does not wait when a logging thread is waiting. + */ + int blockedCount{0}; }; @@ -313,11 +318,11 @@ void AsyncAppender::append(const spi::LoggingEventPtr& event, Pool& p) priv->bufferNotEmpty.notify_all(); break; } - priv->bufferNotEmpty.notify_all(); // // Following code is only reachable if buffer is full or eventCount has overflowed // std::unique_lock<std::mutex> lock(priv->bufferMutex); + priv->bufferNotEmpty.notify_all(); // // if blocking and thread is not already interrupted // and not the dispatcher then @@ -328,10 +333,12 @@ void AsyncAppender::append(const spi::LoggingEventPtr& event, Pool& p) && !priv->closed && (priv->dispatcher.get_id() != std::this_thread::get_id()) ) { + ++priv->blockedCount; priv->bufferNotFull.wait(lock, [this]() { return priv->eventCount - priv->dispatchedCount < priv->bufferSize; }); + --priv->blockedCount; discard = false; } @@ -519,7 +526,7 @@ void AsyncAppender::dispatch() { std::unique_lock<std::mutex> lock(priv->bufferMutex); priv->bufferNotEmpty.wait(lock, [this]() -> bool - { return priv->dispatchedCount != priv->commitCount || priv->closed; } + { return 0 < priv->blockedCount || priv->dispatchedCount != priv->commitCount || priv->closed; } ); } isActive = !priv->isClosed();