This is an automated email from the ASF dual-hosted git repository.

rmiddleton 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 2a381ae4 Fix HierarchyEventListener (#295)
2a381ae4 is described below

commit 2a381ae42e81df35cc61f557a80b833e0e1bb33e
Author: Robert Middleton <[email protected]>
AuthorDate: Mon Nov 20 09:44:17 2023 -0500

    Fix HierarchyEventListener (#295)
    
    Fix HierarchyEventListener
    
    See #286
---
 src/main/cpp/hierarchy.cpp      | 30 +++++++-------
 src/main/cpp/logger.cpp         | 17 +++++++-
 src/test/cpp/loggertestcase.cpp | 86 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+), 16 deletions(-)

diff --git a/src/main/cpp/hierarchy.cpp b/src/main/cpp/hierarchy.cpp
index 1a5b2cf6..c304fab1 100644
--- a/src/main/cpp/hierarchy.cpp
+++ b/src/main/cpp/hierarchy.cpp
@@ -56,7 +56,7 @@ struct Hierarchy::HierarchyPrivate
        }
 
        helpers::Pool pool;
-       mutable std::mutex mutex;
+       mutable std::recursive_mutex mutex;
        mutable std::mutex configuredMutex;
        bool configured;
        bool emittedNoAppenderWarning;
@@ -81,7 +81,7 @@ Hierarchy::Hierarchy() :
 
 Hierarchy::~Hierarchy()
 {
-       std::unique_lock<std::mutex> lock(m_priv->mutex);
+       std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
        for (auto& item : m_priv->loggers)
        {
                if (auto& pLogger = item.second)
@@ -99,7 +99,7 @@ Hierarchy::~Hierarchy()
 
 void Hierarchy::addHierarchyEventListener(const 
spi::HierarchyEventListenerPtr& listener)
 {
-       std::unique_lock<std::mutex> lock(m_priv->mutex);
+       std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
 
        if (std::find(m_priv->listeners.begin(), m_priv->listeners.end(), 
listener) != m_priv->listeners.end())
        {
@@ -113,7 +113,7 @@ void Hierarchy::addHierarchyEventListener(const 
spi::HierarchyEventListenerPtr&
 
 void Hierarchy::removeHierarchyEventListener(const 
spi::HierarchyEventListenerPtr& listener)
 {
-    std::unique_lock<std::mutex> lock(m_priv->mutex);
+       std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
 
     auto found = std::find(m_priv->listeners.begin(), m_priv->listeners.end(), 
listener);
     if(found != m_priv->listeners.end()){
@@ -123,7 +123,7 @@ void Hierarchy::removeHierarchyEventListener(const 
spi::HierarchyEventListenerPt
 
 void Hierarchy::clear()
 {
-       std::unique_lock<std::mutex> lock(m_priv->mutex);
+       std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
        m_priv->loggers.clear();
 }
 
@@ -131,7 +131,7 @@ void Hierarchy::emitNoAppenderWarning(const Logger* logger)
 {
        bool emitWarning = false;
        {
-               std::unique_lock<std::mutex> lock(m_priv->mutex);
+               std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
                emitWarning = !m_priv->emittedNoAppenderWarning;
                m_priv->emittedNoAppenderWarning = true;
        }
@@ -148,7 +148,7 @@ void Hierarchy::emitNoAppenderWarning(const Logger* logger)
 
 LoggerPtr Hierarchy::exists(const LogString& name)
 {
-       std::unique_lock<std::mutex> lock(m_priv->mutex);
+       std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
 
        LoggerPtr logger;
        LoggerMap::iterator it = m_priv->loggers.find(name);
@@ -166,7 +166,7 @@ void Hierarchy::setThreshold(const LevelPtr& l)
 {
        if (l != 0)
        {
-               std::unique_lock<std::mutex> lock(m_priv->mutex);
+               std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
                setThresholdInternal(l);
        }
 }
@@ -202,7 +202,7 @@ void Hierarchy::fireAddAppenderEvent(const Logger* logger, 
const Appender* appen
        setConfigured(true);
        HierarchyEventListenerList clonedList;
        {
-               std::unique_lock<std::mutex> lock(m_priv->mutex);
+               std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
                clonedList = m_priv->listeners;
        }
 
@@ -221,7 +221,7 @@ void Hierarchy::fireRemoveAppenderEvent(const Logger* 
logger, const Appender* ap
 {
        HierarchyEventListenerList clonedList;
        {
-               std::unique_lock<std::mutex> lock(m_priv->mutex);
+               std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
                clonedList = m_priv->listeners;
        }
        HierarchyEventListenerList::iterator it, itEnd = clonedList.end();
@@ -249,7 +249,7 @@ LoggerPtr Hierarchy::getLogger(const LogString& name,
        const spi::LoggerFactoryPtr& factory)
 {
        auto root = getRootLogger();
-       std::unique_lock<std::mutex> lock(m_priv->mutex);
+       std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
 
        LoggerMap::iterator it = m_priv->loggers.find(name);
        LoggerPtr result;
@@ -281,7 +281,7 @@ LoggerPtr Hierarchy::getLogger(const LogString& name,
 
 LoggerList Hierarchy::getCurrentLoggers() const
 {
-       std::unique_lock<std::mutex> lock(m_priv->mutex);
+       std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
 
        LoggerList v;
        for (auto& item : m_priv->loggers)
@@ -294,7 +294,7 @@ LoggerList Hierarchy::getCurrentLoggers() const
 
 LoggerPtr Hierarchy::getRootLogger() const
 {
-       std::unique_lock<std::mutex> lock(m_priv->mutex);
+       std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
        if (!m_priv->root)
        {
                m_priv->root = std::make_shared<RootLogger>(m_priv->pool, 
Level::getDebug());
@@ -321,7 +321,7 @@ void Hierarchy::ensureIsConfigured(std::function<void()> 
configurator)
 
 void Hierarchy::resetConfiguration()
 {
-       std::unique_lock<std::mutex> lock(m_priv->mutex);
+       std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
 
        if (m_priv->root)
        {
@@ -349,7 +349,7 @@ void Hierarchy::resetConfiguration()
 
 void Hierarchy::shutdown()
 {
-       std::unique_lock<std::mutex> lock(m_priv->mutex);
+       std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
 
        shutdownInternal();
 }
diff --git a/src/main/cpp/logger.cpp b/src/main/cpp/logger.cpp
index 846c7566..d90cfcc8 100644
--- a/src/main/cpp/logger.cpp
+++ b/src/main/cpp/logger.cpp
@@ -502,17 +502,32 @@ void Logger::l7dlog(const LevelPtr& level1, const 
std::string& key,
 
 void Logger::removeAllAppenders()
 {
+       AppenderList currentAppenders = m_priv->aai.getAllAppenders();
        m_priv->aai.removeAllAppenders();
+
+       auto rep = getHierarchy();
+       if(rep){
+               for(AppenderPtr appender : currentAppenders){
+                       rep->fireRemoveAppenderEvent(this, appender.get());
+               }
+       }
 }
 
 void Logger::removeAppender(const AppenderPtr appender)
 {
        m_priv->aai.removeAppender(appender);
+       if (auto rep = getHierarchy())
+       {
+               rep->fireRemoveAppenderEvent(this, appender.get());
+       }
 }
 
 void Logger::removeAppender(const LogString& name1)
 {
-       m_priv->aai.removeAppender(name1);
+       AppenderPtr appender = m_priv->aai.getAppender(name1);
+       if(appender){
+               removeAppender(appender);
+       }
 }
 
 void Logger::removeHierarchy()
diff --git a/src/test/cpp/loggertestcase.cpp b/src/test/cpp/loggertestcase.cpp
index 942b829e..e18f6897 100644
--- a/src/test/cpp/loggertestcase.cpp
+++ b/src/test/cpp/loggertestcase.cpp
@@ -60,6 +60,31 @@ class CountingAppender : public AppenderSkeleton
                }
 };
 
+class CountingListener : public HierarchyEventListener{
+public:
+       DECLARE_LOG4CXX_OBJECT(CountingListener)
+       BEGIN_LOG4CXX_CAST_MAP()
+       LOG4CXX_CAST_ENTRY(CountingListener)
+       END_LOG4CXX_CAST_MAP()
+
+       int numRemoved = 0;
+       int numAdded = 0;
+
+       void addAppenderEvent(
+               const Logger* logger,
+                       const Appender* appender){
+               numAdded++;
+       }
+
+       void removeAppenderEvent(
+               const Logger* logger,
+                       const Appender* appender){
+               numRemoved++;
+       }
+};
+
+IMPLEMENT_LOG4CXX_OBJECT(CountingListener);
+
 LOGUNIT_CLASS(LoggerTestCase)
 {
        LOGUNIT_TEST_SUITE(LoggerTestCase);
@@ -76,6 +101,9 @@ LOGUNIT_CLASS(LoggerTestCase)
        LOGUNIT_TEST(testHierarchy1);
        LOGUNIT_TEST(testTrace);
        LOGUNIT_TEST(testIsTraceEnabled);
+       LOGUNIT_TEST(testAddingListeners);
+       LOGUNIT_TEST(testAddingAndRemovingListeners);
+       LOGUNIT_TEST(testAddingAndRemovingListeners2);
        LOGUNIT_TEST_SUITE_END();
 
 public:
@@ -488,6 +516,64 @@ public:
                LOGUNIT_ASSERT_EQUAL(true, Logger::isErrorEnabledFor(root));
        }
 
+       void testAddingListeners()
+       {
+               auto appender = std::shared_ptr<CountingAppender>(new 
CountingAppender);
+               LoggerPtr root = Logger::getRootLogger();
+               std::shared_ptr<CountingListener> listener = 
std::shared_ptr<CountingListener>(new CountingListener());
+
+               
root->getLoggerRepository()->addHierarchyEventListener(listener);
+
+               root->addAppender(appender);
+
+               LOGUNIT_ASSERT_EQUAL(1, listener->numAdded);
+               LOGUNIT_ASSERT_EQUAL(0, listener->numRemoved);
+       }
+
+       void testAddingAndRemovingListeners()
+       {
+               auto appender = std::shared_ptr<CountingAppender>(new 
CountingAppender);
+               LoggerPtr root = Logger::getRootLogger();
+               std::shared_ptr<CountingListener> listener = 
std::shared_ptr<CountingListener>(new CountingListener());
+
+               
root->getLoggerRepository()->addHierarchyEventListener(listener);
+
+               root->addAppender(appender);
+
+               LOGUNIT_ASSERT_EQUAL(1, listener->numAdded);
+               LOGUNIT_ASSERT_EQUAL(0, listener->numRemoved);
+
+               root->removeAppender(appender);
+
+               LOGUNIT_ASSERT_EQUAL(1, listener->numAdded);
+               LOGUNIT_ASSERT_EQUAL(1, listener->numRemoved);
+       }
+
+       void testAddingAndRemovingListeners2()
+       {
+               auto appender = std::shared_ptr<CountingAppender>(new 
CountingAppender);
+               auto appender2 = std::shared_ptr<CountingAppender>(new 
CountingAppender);
+               LoggerPtr root = Logger::getRootLogger();
+               std::shared_ptr<CountingListener> listener = 
std::shared_ptr<CountingListener>(new CountingListener());
+
+               
root->getLoggerRepository()->addHierarchyEventListener(listener);
+
+               root->addAppender(appender);
+
+               LOGUNIT_ASSERT_EQUAL(1, listener->numAdded);
+               LOGUNIT_ASSERT_EQUAL(0, listener->numRemoved);
+
+               root->addAppender(appender2);
+
+               LOGUNIT_ASSERT_EQUAL(2, listener->numAdded);
+               LOGUNIT_ASSERT_EQUAL(0, listener->numRemoved);
+
+               root->removeAllAppenders();
+
+               LOGUNIT_ASSERT_EQUAL(2, listener->numAdded);
+               LOGUNIT_ASSERT_EQUAL(2, listener->numRemoved);
+       }
+
 protected:
        static LogString MSG;
        LoggerPtr logger;

Reply via email to