Skip to content

Commit

Permalink
Merge branch 'master' into static_registration_warning
Browse files Browse the repository at this point in the history
  • Loading branch information
stephen-webb committed Jul 25, 2024
2 parents 85e5e4a + 824563d commit 79a1728
Show file tree
Hide file tree
Showing 18 changed files with 641 additions and 484 deletions.
79 changes: 79 additions & 0 deletions .github/workflows/log4cxx-msys2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: log4cxx-msys2

on: [push, pull_request]

jobs:
job:
name: ${{ matrix.env }}-${{ matrix.cxx }}-build-and-test
runs-on: windows-2022
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
name: [ ucrt64-clang, ucrt64-gnu ]
include:
- name: ucrt64-clang
sys: ucrt64
env: ucrt-x86_64
compiler-package: clang
cxx: clang++
- name: ucrt64-gnu
sys: ucrt64
env: ucrt-x86_64
compiler-package: gcc
cxx: g++
- name: mingw64-clang
sys: mingw64
env: x86_64
compiler-package: clang
cxx: clang++
- name: mingw64-gnu
sys: mingw64
env: x86_64
compiler-package: gcc
cxx: g++

steps:
- uses: msys2/setup-msys2@v2
with:
msystem: ${{matrix.sys}}
update: true
install: >-
git
mingw-w64-${{ matrix.env }}-${{ matrix.compiler-package }}
mingw-w64-${{ matrix.env }}-ccmake
mingw-w64-${{ matrix.env }}-ninja
mingw-w64-${{ matrix.env }}-apr-util
sed
zip
- uses: actions/checkout@v4
with:
persist-credentials: false # do not persist auth token in the local git config
path: log4cxx

- name: 'configure and build'
shell: msys2 {0}
run: |
cmake -G Ninja -S log4cxx -B log4cxx/build -DCMAKE_CXX_COMPILER=${{ matrix.cxx }} -DCMAKE_BUILD_TYPE=Debug
cmake --build log4cxx/build
- name: 'run unit tests'
shell: msys2 {0}
run: |
cd log4cxx/build
ctest -C Debug --output-on-failure
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ get_directory_property( HAS_SYSLOG DIRECTORY src/main/include DEFINITION HAS_SYS
get_directory_property( FILESYSTEM_IMPL DIRECTORY src DEFINITION FILESYSTEM_IMPL )
get_directory_property( STD_MAKE_UNIQUE_IMPL DIRECTORY src DEFINITION STD_MAKE_UNIQUE_IMPL )
get_directory_property( STD_LIB_HAS_UNICODE_STRING DIRECTORY src DEFINITION STD_LIB_HAS_UNICODE_STRING )
get_directory_property( HAS_THREAD_LOCAL DIRECTORY src DEFINITION HAS_THREAD_LOCAL )

foreach(varName HAS_STD_LOCALE HAS_ODBC HAS_MBSRTOWCS HAS_WCSTOMBS HAS_FWIDE HAS_LIBESMTP HAS_SYSLOG HAS_FMT)
if(${varName} EQUAL 0)
Expand Down
7 changes: 6 additions & 1 deletion src/cmake/compiler-features/check-compiler-support.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@
#

# Does the compiler support thread_local?
try_compile(HAS_THREAD_LOCAL "${CMAKE_BINARY_DIR}/Testing/thread-local-test"
if(MINGW)
# As at 2024-7-19 the msys2 ucrt-x86_64 runtime terminates with error c0000374 during thread local data cleanup
set(HAS_THREAD_LOCAL FALSE)
else()
try_compile(HAS_THREAD_LOCAL "${CMAKE_BINARY_DIR}/Testing/thread-local-test"
"${CMAKE_CURRENT_LIST_DIR}/test-thread-local.cpp"
CXX_STANDARD 11
)
endif()

# Does the standard library support std::make_unique<T>>?
try_compile(STD_MAKE_UNIQUE_FOUND "${CMAKE_BINARY_DIR}/boost-fallback-compile-tests"
Expand Down
86 changes: 47 additions & 39 deletions src/main/cpp/asyncappender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@
* limitations under the License.
*/


#include <log4cxx/asyncappender.h>


#include <log4cxx/helpers/loglog.h>
#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/helpers/stringhelper.h>
Expand Down Expand Up @@ -105,30 +103,34 @@ typedef std::map<LogString, DiscardSummary> DiscardMap;
#endif

#ifdef __cpp_lib_hardware_interference_size
using std::hardware_constructive_interference_size;
using std::hardware_destructive_interference_size;
using std::hardware_constructive_interference_size;
using std::hardware_destructive_interference_size;
#else
// 64 bytes on x86-64 │ L1_CACHE_BYTES │ L1_CACHE_SHIFT │ __cacheline_aligned │ ...
constexpr std::size_t hardware_constructive_interference_size = 64;
constexpr std::size_t hardware_destructive_interference_size = 64;
// 64 bytes on x86-64 │ L1_CACHE_BYTES │ L1_CACHE_SHIFT │ __cacheline_aligned │ ...
constexpr std::size_t hardware_constructive_interference_size = 64;
constexpr std::size_t hardware_destructive_interference_size = 64;
#endif

struct AsyncAppender::AsyncAppenderPriv : public AppenderSkeleton::AppenderSkeletonPrivate
{
AsyncAppenderPriv() :
AppenderSkeletonPrivate(),
buffer(DEFAULT_BUFFER_SIZE),
bufferSize(DEFAULT_BUFFER_SIZE),
dispatcher(),
locationInfo(false),
blocking(true)
AsyncAppenderPriv()
: AppenderSkeletonPrivate()
, buffer(DEFAULT_BUFFER_SIZE)
, bufferSize(DEFAULT_BUFFER_SIZE)
, dispatcher()
, locationInfo(false)
, blocking(true)
#if LOG4CXX_EVENTS_AT_EXIT
, atExitRegistryRaii([this]{stopDispatcher();})
#endif
, eventCount(0)
, dispatchedCount(0)
, commitCount(0)
{ }

~AsyncAppenderPriv()
{
stopDispatcher();
}

/**
Expand Down Expand Up @@ -171,10 +173,7 @@ struct AsyncAppender::AsyncAppenderPriv : public AppenderSkeleton::AppenderSkele

void stopDispatcher()
{
{
std::lock_guard<std::mutex> lock(bufferMutex);
closed = true;
}
this->setClosed();
bufferNotEmpty.notify_all();
bufferNotFull.notify_all();

Expand Down Expand Up @@ -212,6 +211,18 @@ struct AsyncAppender::AsyncAppenderPriv : public AppenderSkeleton::AppenderSkele
* Used to communicate to the dispatch thread when an event is committed in buffer.
*/
alignas(hardware_constructive_interference_size) std::atomic<size_t> commitCount;

bool isClosed()
{
std::lock_guard<std::mutex> lock(this->bufferMutex);
return this->closed;
}

void setClosed()
{
std::lock_guard<std::mutex> lock(this->bufferMutex);
this->closed = true;
}
};


Expand Down Expand Up @@ -271,16 +282,12 @@ void AsyncAppender::append(const spi::LoggingEventPtr& event, Pool& p)
priv->appenders.appendLoopOnAppenders(event, p);
}

// Set the NDC and MDC for the calling thread as these
// LoggingEvent fields were not set at event creation time.
LogString ndcVal;
event->getNDC(ndcVal);
// Get a copy of this thread's MDC.
event->getMDCCopy();
// Get a copy of this thread's diagnostic context
event->LoadDC();

if (!priv->dispatcher.joinable())
{
std::lock_guard<std::mutex> lock(priv->bufferMutex);
std::lock_guard<std::recursive_mutex> lock(priv->mutex);
if (!priv->dispatcher.joinable())
priv->dispatcher = ThreadUtility::instance()->createThread( LOG4CXX_STR("AsyncAppender"), &AsyncAppender::dispatch, this );
}
Expand Down Expand Up @@ -515,7 +522,7 @@ void AsyncAppender::dispatch()
{ return priv->dispatchedCount != priv->commitCount || priv->closed; }
);
}
isActive = !priv->closed;
isActive = !priv->isClosed();

while (events.size() < priv->bufferSize && priv->dispatchedCount != priv->commitCount)
{
Expand Down Expand Up @@ -545,34 +552,35 @@ void AsyncAppender::dispatch()
}
catch (std::exception& ex)
{
if (isActive)
if (!priv->isClosed())
{
priv->errorHandler->error(LOG4CXX_STR("async dispatcher"), ex, 0, item);
isActive = false;
}
}
catch (...)
{
if (isActive)
if (!priv->isClosed())
{
priv->errorHandler->error(LOG4CXX_STR("async dispatcher"));
isActive = false;
}
}
}
if (!isActive && LogLog::isDebugEnabled())
}
if (LogLog::isDebugEnabled())
{
Pool p;
LogString msg(LOG4CXX_STR("AsyncAppender"));
msg += LOG4CXX_STR(" discardCount ");
StringHelper::toString(discardCount, p, msg);
msg += LOG4CXX_STR(" pendingCountHistogram");
for (auto item : pendingCountHistogram)
{
LogString msg(LOG4CXX_STR("AsyncAppender"));
msg += LOG4CXX_STR(" discardCount ");
StringHelper::toString(discardCount, p, msg);
msg += LOG4CXX_STR(" pendingCountHistogram");
for (auto item : pendingCountHistogram)
{
msg += logchar(' ');
StringHelper::toString(item, p, msg);
}
LogLog::debug(msg);
msg += logchar(' ');
StringHelper::toString(item, p, msg);
}
LogLog::debug(msg);
}

}
10 changes: 6 additions & 4 deletions src/main/cpp/hierarchy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ struct Hierarchy::HierarchyPrivate
ProvisionNodeMap provisionNodes;

std::vector<AppenderPtr> allAppenders;

mutable std::mutex listenerMutex;
};

IMPLEMENT_LOG4CXX_OBJECT(Hierarchy)
Expand Down Expand Up @@ -91,7 +93,7 @@ Hierarchy::~Hierarchy()

void Hierarchy::addHierarchyEventListener(const spi::HierarchyEventListenerPtr& listener)
{
std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
std::lock_guard<std::mutex> lock(m_priv->listenerMutex);

if (std::find(m_priv->listeners.begin(), m_priv->listeners.end(), listener) != m_priv->listeners.end())
{
Expand All @@ -105,7 +107,7 @@ void Hierarchy::addHierarchyEventListener(const spi::HierarchyEventListenerPtr&

void Hierarchy::removeHierarchyEventListener(const spi::HierarchyEventListenerPtr& listener)
{
std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
std::lock_guard<std::mutex> lock(m_priv->listenerMutex);

auto found = std::find(m_priv->listeners.begin(), m_priv->listeners.end(), listener);
if(found != m_priv->listeners.end()){
Expand Down Expand Up @@ -194,7 +196,7 @@ void Hierarchy::fireAddAppenderEvent(const Logger* logger, const Appender* appen
setConfigured(true);
HierarchyEventListenerList clonedList;
{
std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
std::lock_guard<std::mutex> lock(m_priv->listenerMutex);
clonedList = m_priv->listeners;
}

Expand All @@ -207,7 +209,7 @@ void Hierarchy::fireRemoveAppenderEvent(const Logger* logger, const Appender* ap
{
HierarchyEventListenerList clonedList;
{
std::lock_guard<std::recursive_mutex> lock(m_priv->mutex);
std::lock_guard<std::mutex> lock(m_priv->listenerMutex);
clonedList = m_priv->listeners;
}
for (auto& item : clonedList)
Expand Down
Loading

0 comments on commit 79a1728

Please sign in to comment.