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 96ec5230 Prevent potential deadlock on shutdown when using 
AsyncAppender (#511)
96ec5230 is described below

commit 96ec52307cace1f82f44ea7154ebcbb7dda8eec9
Author: Stephen Webb <stephen.w...@ieee.org>
AuthorDate: Thu Jul 17 11:10:58 2025 +1000

    Prevent potential deadlock on shutdown when using AsyncAppender (#511)
    
    * Document best practice in the simple example
    
    * Document that LogManager::shutdown must be called to prevent UB
---
 src/examples/cpp/MyApp1.cpp              |  7 ++++---
 src/main/cpp/loglog.cpp                  |  3 ++-
 src/main/include/log4cxx/asyncappender.h | 13 +++++++------
 3 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/src/examples/cpp/MyApp1.cpp b/src/examples/cpp/MyApp1.cpp
index 2cc170bd..faf24938 100644
--- a/src/examples/cpp/MyApp1.cpp
+++ b/src/examples/cpp/MyApp1.cpp
@@ -1,11 +1,11 @@
-#include <log4cxx/logger.h>
+#include <log4cxx/logmanager.h>
 #include <log4cxx/basicconfigurator.h>
 
-static auto logger = log4cxx::Logger::getLogger("MyApp");
+static auto logger = log4cxx::LogManager::getLogger("MyApp");
 
 void foo() {
        // Get a logger that is a child of the statically declared logger
-       auto fooLogger = log4cxx::Logger::getLogger("MyApp.foo");
+       auto fooLogger = log4cxx::LogManager::getLogger("MyApp.foo");
        LOG4CXX_TRACE(fooLogger, "Doing foo at trace level");
        LOG4CXX_DEBUG(fooLogger, "Doing foo at debug level");
        LOG4CXX_INFO(fooLogger, "Doing foo at info level");
@@ -20,5 +20,6 @@ int main(int argc, char **argv) {
        LOG4CXX_INFO(logger, "Entering application.");
        foo();
        LOG4CXX_INFO(logger, "Exiting application.");
+       log4cxx::LogManager::shutdown();
        return EXIT_SUCCESS;
 }
diff --git a/src/main/cpp/loglog.cpp b/src/main/cpp/loglog.cpp
index c5384c4d..016485c6 100644
--- a/src/main/cpp/loglog.cpp
+++ b/src/main/cpp/loglog.cpp
@@ -57,7 +57,8 @@ LogLog::LogLog() :
        m_priv->debugEnabled = OptionConverter::toBoolean(log4cxxDebug, false);
 }
 
-LogLog::~LogLog(){}
+LogLog::~LogLog()
+{ m_priv.reset(); }
 
 LogLog& LogLog::getInstance()
 {
diff --git a/src/main/include/log4cxx/asyncappender.h 
b/src/main/include/log4cxx/asyncappender.h
index 3b2ce467..c8386f6b 100644
--- a/src/main/include/log4cxx/asyncappender.h
+++ b/src/main/include/log4cxx/asyncappender.h
@@ -34,7 +34,13 @@ The AsyncAppender stores the logging event in a bounded 
buffer
 and then returns control to the application.
 A separate thread forwards events to the attached appender(s).
 
-The AsyncAppender is useful when outputting to a slow event sink,
+<b>Important notes:</b>
+- Your application must call LogManager::shutdown when it exits
+to prevent undefined behaviour when using this appender.
+- Runtime configuration requires an XML configuration file
+(see the example below).
+
+This appender is useful when outputting to a slow event sink,
 for example, a remote SMTP server or a database.
 Attaching a FileAppender to AsyncAppender
 to reduce logging overhead is not recommended
@@ -47,11 +53,6 @@ You can attach multiple appenders to an AsyncAppender by:
 to the <b>appender class="AsyncAppender"</b> element
 when using runtime configuration.
 
-<b>Important note:</b> The <code>AsyncAppender</code> can only
-be configured at runtime using XML,
-i.e. when the application uses {@link xml::DOMConfigurator DOMConfigurator}
-to load the cofiguration file.
-
 Here is a sample configuration file:
 \include async-example.xml
 

Reply via email to