You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by sw...@apache.org on 2026/09/25 02:40:56 UTC
(logging-log4cxx) branch master updated: Ensure the internal logger lifetime is longer than other objects (#766)
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 1e0b0d42 Ensure the internal logger lifetime is longer than other objects (#766)
1e0b0d42 is described below
commit 1e0b0d4233567aebd56b93406cf0b2187a3ec0fc
Author: Stephen Webb <st...@ieee.org>
AuthorDate: Fri Sep 25 12:40:50 2026 +1000
Ensure the internal logger lifetime is longer than other objects (#766)
* The class register now only contains valid entries
---
src/main/cpp/aprinitializer.cpp | 4 +--
src/main/cpp/class.cpp | 36 +++++++++++++----------
src/main/cpp/loglog.cpp | 49 ++++++++++++++++++++-----------
src/main/cpp/transform.cpp | 1 -
src/main/include/log4cxx/helpers/loglog.h | 12 ++++----
5 files changed, 62 insertions(+), 40 deletions(-)
diff --git a/src/main/cpp/aprinitializer.cpp b/src/main/cpp/aprinitializer.cpp
index b9fe3052..73292418 100644
--- a/src/main/cpp/aprinitializer.cpp
+++ b/src/main/cpp/aprinitializer.cpp
@@ -145,8 +145,8 @@ const ObjectPtr& APRInitializer::findOrAddObject(size_t key, std::function<Objec
std::lock_guard<std::mutex> lock(m_priv->mutex);
if (m_priv->objects.empty())
{
- // Ensure the internal logger has a longer life than other Log4cxx static data
- LogLog::debug(LOG4CXX_STR("Started"));
+ // Ensure the internal logger has a longer life than other Log4cxx data
+ m_priv->objects.emplace_back(typeid(LogLog).hash_code(), LogLog::_createInstance());
}
auto pItem = std::find_if(m_priv->objects.begin(), m_priv->objects.end()
, [key](const IdentifiedObject& item) { return item.first == key; }
diff --git a/src/main/cpp/class.cpp b/src/main/cpp/class.cpp
index 974c3651..39acfc27 100644
--- a/src/main/cpp/class.cpp
+++ b/src/main/cpp/class.cpp
@@ -26,6 +26,8 @@
#define LOG4CXX 1
#endif
#include <log4cxx/private/log4cxx_private.h>
+#include <log4cxx/helpers/aprinitializer.h>
+#include <log4cxx/helpers/singletonholder.h>
#include <log4cxx/asyncappender.h>
@@ -107,60 +109,64 @@ Object* Class::newInstance() const
#endif
}
-
-
Class::ClassMap& Class::getRegistry()
{
- static WideLife<ClassMap> registry;
- return registry;
+ using ClassMapHolder = SingletonHolder<ClassMap>;
+ auto pHolder = APRInitializer::getOrAddUnique<ClassMapHolder>
+ ( []() -> ObjectPtr
+ { return std::make_shared<ClassMapHolder>(); }
+ );
+ return pHolder->value();
}
const Class& Class::forName(const LogString& className)
{
LogString lowerName(StringHelper::toLowerCase(className));
+ auto& classRegister = getRegistry();
//
// check registry using full class name
//
- const Class* clazz = getRegistry()[lowerName];
+ auto pEntry = classRegister.find(lowerName);
- if (clazz == 0)
+ if (classRegister.end() == pEntry)
{
LogString::size_type pos = className.find_last_of(LOG4CXX_STR(".$"));
if (pos != LogString::npos)
{
LogString terminalName(lowerName, pos + 1, LogString::npos);
- clazz = getRegistry()[terminalName];
+ pEntry = classRegister.find(terminalName);
- if (clazz == 0)
+ if (classRegister.end() == pEntry)
{
registerClasses();
- clazz = getRegistry()[lowerName];
+ pEntry = classRegister.find(lowerName);
- if (clazz == 0)
+ if (classRegister.end() == pEntry)
{
- clazz = getRegistry()[terminalName];
+ pEntry = classRegister.find(terminalName);
}
}
}
else
{
registerClasses();
- clazz = getRegistry()[lowerName];
+ pEntry = classRegister.find(lowerName);
}
}
- if (clazz == 0)
+ if (classRegister.end() == pEntry || !pEntry->second)
{
throw ClassNotFoundException(className);
}
- return *clazz;
+ return *pEntry->second;
}
bool Class::registerClass(const Class& newClass)
{
- getRegistry()[StringHelper::toLowerCase(newClass.getName())] = &newClass;
+ auto& classRegister = getRegistry();
+ classRegister[StringHelper::toLowerCase(newClass.getName())] = &newClass;
return true;
}
diff --git a/src/main/cpp/loglog.cpp b/src/main/cpp/loglog.cpp
index 3aab3dac..bb9b0444 100644
--- a/src/main/cpp/loglog.cpp
+++ b/src/main/cpp/loglog.cpp
@@ -44,6 +44,15 @@ struct LogLog::LogLogPrivate {
quietMode = true; // Prevent output after deletion by onexit processing chain.
}
+ static LogLog* parent;
+
+ static LogLogPrivate* getInstance()
+ {
+ if (!parent)
+ return nullptr;
+ return parent->m_priv.get();
+ }
+
bool debugEnabled;
/**
@@ -81,6 +90,8 @@ struct LogLog::LogLogPrivate {
}
};
+LogLog* LogLog::LogLogPrivate::parent{ nullptr };
+
LogLog::LogLog() :
m_priv(std::make_unique<LogLogPrivate>())
{
@@ -91,18 +102,22 @@ LogLog::LogLog() :
}
LogLog::~LogLog()
-{ m_priv.reset(); }
-
-LogLog& LogLog::getInstance()
{
- static WideLife<LogLog> internalLogger;
+ LogLogPrivate::parent = nullptr;
+}
- return internalLogger;
+ObjectPtr LogLog::_createInstance()
+{
+ using LogLogHolder = SingletonHolder<LogLog>;
+ auto pLogLog = std::make_shared<LogLogHolder>();
+ LogLogPrivate::parent = &pLogLog->value();
+ debug(LOG4CXX_STR("Started"));
+ return pLogLog;
}
bool LogLog::isDebugEnabled()
{
- auto p = getInstance().m_priv.get();
+ auto p = LogLogPrivate::getInstance();
return p && !p->quietMode // Not deleted by onexit processing?
&& p->debugEnabled;
}
@@ -119,26 +134,26 @@ bool LogLog::isTraceEnabledFor(const LoggerPtr& category)
void LogLog::setInternalDebugging(bool debugEnabled1)
{
- auto p = getInstance().m_priv.get();
+ auto p = LogLogPrivate::getInstance();
if (p && !p->quietMode) // Not deleted by onexit processing?
p->debugEnabled = debugEnabled1;
}
bool LogLog::isColorEnabled()
{
- auto p = getInstance().m_priv.get();
+ auto p = LogLogPrivate::getInstance();
return p && !p->errorPrefix.empty();
}
void LogLog::setColorEnabled(bool newValue)
{
- if (auto p = getInstance().m_priv.get())
+ if (auto p = LogLogPrivate::getInstance())
p->setColorEnabled(newValue);
}
void LogLog::debug(const LogString& msg)
{
- auto p = getInstance().m_priv.get();
+ auto p = LogLogPrivate::getInstance();
if (p && !p->quietMode) // Not deleted by onexit processing?
{
if (!p->debugEnabled)
@@ -153,7 +168,7 @@ void LogLog::debug(const LogString& msg)
void LogLog::debug(const LogString& msg, const std::exception& e)
{
- auto p = getInstance().m_priv.get();
+ auto p = LogLogPrivate::getInstance();
if (p && !p->quietMode) // Not deleted by onexit processing?
{
if (!p->debugEnabled)
@@ -168,7 +183,7 @@ void LogLog::debug(const LogString& msg, const std::exception& e)
void LogLog::error(const LogString& msg)
{
- auto p = getInstance().m_priv.get();
+ auto p = LogLogPrivate::getInstance();
if (p && !p->quietMode) // Not deleted by onexit processing?
{
std::lock_guard<std::mutex> lock(p->mutex);
@@ -179,7 +194,7 @@ void LogLog::error(const LogString& msg)
void LogLog::error(const LogString& msg, const std::exception& e)
{
- auto p = getInstance().m_priv.get();
+ auto p = LogLogPrivate::getInstance();
if (p && !p->quietMode) // Not deleted by onexit processing?
{
std::lock_guard<std::mutex> lock(p->mutex);
@@ -203,7 +218,7 @@ void LogLog::trace(const LoggerPtr& category, const std::string& msg)
void LogLog::trace(const LoggerPtr& category, const LogString& msg)
{
- auto p = getInstance().m_priv.get();
+ auto p = LogLogPrivate::getInstance();
if (p && !p->quietMode) // Not deleted by onexit processing?
{
if (!p->debugEnabled)
@@ -218,7 +233,7 @@ void LogLog::trace(const LoggerPtr& category, const LogString& msg)
void LogLog::setQuietMode(bool quietMode1)
{
- auto p = getInstance().m_priv.get();
+ auto p = LogLogPrivate::getInstance();
std::lock_guard<std::mutex> lock(p->mutex);
p->quietMode = quietMode1;
@@ -226,7 +241,7 @@ void LogLog::setQuietMode(bool quietMode1)
void LogLog::warn(const LogString& msg)
{
- auto p = getInstance().m_priv.get();
+ auto p = LogLogPrivate::getInstance();
if (p && !p->quietMode) // Not deleted by onexit processing?
{
std::lock_guard<std::mutex> lock(p->mutex);
@@ -236,7 +251,7 @@ void LogLog::warn(const LogString& msg)
void LogLog::warn(const LogString& msg, const std::exception& e)
{
- auto p = getInstance().m_priv.get();
+ auto p = LogLogPrivate::getInstance();
if (p && !p->quietMode) // Not deleted by onexit processing?
{
std::lock_guard<std::mutex> lock(p->mutex);
diff --git a/src/main/cpp/transform.cpp b/src/main/cpp/transform.cpp
index ee1ee457..c3db7b38 100644
--- a/src/main/cpp/transform.cpp
+++ b/src/main/cpp/transform.cpp
@@ -18,7 +18,6 @@
#include <log4cxx/logstring.h>
#include <log4cxx/helpers/transform.h>
#include <log4cxx/helpers/transcoder.h>
-#include <log4cxx/helpers/widelife.h>
#include <functional>
using namespace LOG4CXX_NS;
diff --git a/src/main/include/log4cxx/helpers/loglog.h b/src/main/include/log4cxx/helpers/loglog.h
index bd64f792..15c82ef8 100644
--- a/src/main/include/log4cxx/helpers/loglog.h
+++ b/src/main/include/log4cxx/helpers/loglog.h
@@ -20,14 +20,13 @@
#include <log4cxx/logstring.h>
#include <log4cxx/logger.h>
-#include <log4cxx/helpers/widelife.h>
-#include <exception>
-#include <mutex>
+#include <log4cxx/helpers/singletonholder.h>
namespace LOG4CXX_NS
{
namespace helpers
{
+
/**
This class used to output log statements from within the log4cxx package.
@@ -44,11 +43,10 @@ class LOG4CXX_EXPORT LogLog
private:
LOG4CXX_DECLARE_PRIVATE_MEMBER_PTR(LogLogPrivate, m_priv)
- friend WideLife<LogLog>;
+ friend class SingletonHolder<LogLog>;
LogLog();
LogLog(const LogLog&);
LogLog& operator=(const LogLog&);
- static LogLog& getInstance();
public:
~LogLog();
@@ -137,6 +135,10 @@ class LOG4CXX_EXPORT LogLog
*/
static LoggerPtr getLogger(const LogString& name);
+ /**
+ Internal use only.
+ */
+ static ObjectPtr _createInstance();
private:
static void emit_log(const LogString& prefix, const LogString& msg, const LogString& suffix);
static void emit_log(const LogString& prefix, const std::exception& ex, const LogString& suffix);