Skip to content

Commit

Permalink
Add msys2 testing to Github CI (#394)
Browse files Browse the repository at this point in the history
* Report thread_local support in configuration summary

* Add items to the change report

* Improve ThreadSpecificData robustness and simpilicity

* Replace os dependent code with with std::this_thread::get_id()

* Fallback to std::this_thread::get_id()
  • Loading branch information
swebb2066 authored Jul 22, 2024
1 parent 4f0abc2 commit b00813c
Show file tree
Hide file tree
Showing 11 changed files with 216 additions and 129 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
31 changes: 8 additions & 23 deletions src/main/cpp/loggingevent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <log4cxx/logger.h>
#include <log4cxx/private/log4cxx_private.h>
#include <log4cxx/helpers/date.h>
#include <thread>

using namespace LOG4CXX_NS;
using namespace LOG4CXX_NS::spi;
Expand Down Expand Up @@ -333,29 +334,10 @@ LoggingEvent::KeySet LoggingEvent::getPropertyKeySet() const

const LogString& LoggingEvent::getCurrentThreadName()
{
#if LOG4CXX_HAS_PTHREAD_SELF && !(defined(_WIN32) && defined(_LIBCPP_VERSION))
using ThreadIdType = pthread_t;
ThreadIdType threadId = pthread_self();
#elif defined(_WIN32)
using ThreadIdType = DWORD;
ThreadIdType threadId = GetCurrentThreadId();
#else
using ThreadIdType = int;
ThreadIdType threadId = 0;
#endif

#if LOG4CXX_HAS_THREAD_LOCAL
thread_local LogString thread_id_string;
#else
using ListItem = std::pair<ThreadIdType, LogString>;
static std::list<ListItem> thread_id_map;
static std::mutex mutex;
std::lock_guard<std::mutex> lock(mutex);
auto pThreadId = std::find_if(thread_id_map.begin(), thread_id_map.end()
, [threadId](const ListItem& item) { return threadId == item.first; });
if (thread_id_map.end() == pThreadId)
pThreadId = thread_id_map.insert(thread_id_map.begin(), ListItem(threadId, LogString()));
LogString& thread_id_string = pThreadId->second;
LogString& thread_id_string = ThreadSpecificData::getThreadIdString();
#endif
if ( !thread_id_string.empty() )
{
Expand All @@ -365,15 +347,18 @@ const LogString& LoggingEvent::getCurrentThreadName()
#if LOG4CXX_HAS_PTHREAD_SELF && !(defined(_WIN32) && defined(_LIBCPP_VERSION))
// pthread_t encoded in HEX takes needs as many characters
// as two times the size of the type, plus an additional null byte.
auto threadId = pthread_self();
char result[sizeof(pthread_t) * 3 + 10];
apr_snprintf(result, sizeof(result), LOG4CXX_APR_THREAD_FMTSPEC, (void*) &threadId);
thread_id_string = Transcoder::decode(result);
#elif defined(_WIN32)
char result[20];
apr_snprintf(result, sizeof(result), LOG4CXX_WIN32_THREAD_FMTSPEC, threadId);
apr_snprintf(result, sizeof(result), LOG4CXX_WIN32_THREAD_FMTSPEC, GetCurrentThreadId());
thread_id_string = Transcoder::decode(result);
#else
thread_id_string = LOG4CXX_STR("0x00000000");
std::stringstream ss;
ss << std::hex << "0x" << std::this_thread::get_id();
thread_id_string = Transcoder::decode(ss.str().c_str());
#endif
return thread_id_string;
}
Expand All @@ -383,7 +368,7 @@ const LogString& LoggingEvent::getCurrentThreadUserName()
#if LOG4CXX_HAS_THREAD_LOCAL
thread_local LogString thread_name;
#else
static WideLife<LogString> thread_name = LOG4CXX_STR("(noname)");
LogString& thread_name = ThreadSpecificData::getThreadName();
#endif
if( !thread_name.empty() ){
return thread_name;
Expand Down
17 changes: 7 additions & 10 deletions src/main/cpp/messagebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#define LOG4CXX 1
#endif
#include <log4cxx/private/log4cxx_private.h>
#if !LOG4CXX_HAS_THREAD_LOCAL
#include <log4cxx/helpers/threadspecificdata.h>
#endif

using namespace LOG4CXX_NS::helpers;

Expand All @@ -40,31 +43,25 @@ struct StringOrStream
StringOrStream()
: stream(nullptr)
{}
~StringOrStream()
{
#if !LOG4CXX_HAS_THREAD_LOCAL
delete stream;
#endif
}
/**
* Move the character buffer from \c buf to \c stream
*/
std::basic_ostringstream<T>& StreamFromBuf()
{
if (!this->stream)
{
#if LOG4CXX_HAS_THREAD_LOCAL
const static std::basic_ostringstream<T> initialState;
#if LOG4CXX_HAS_THREAD_LOCAL
thread_local static std::basic_ostringstream<T> sStream;
#else
auto& sStream = ThreadSpecificData::getStringStream<T>();
#endif
this->stream = &sStream;
this->stream->clear();
this->stream->precision(initialState.precision());
this->stream->width(initialState.width());
this->stream->setf(initialState.flags(), ~initialState.flags());
this->stream->fill(initialState.fill());
#else
this->stream = new std::basic_ostringstream<T>();
#endif
auto index = this->buf.size();
this->stream->str(std::move(this->buf));
this->stream->seekp(index);
Expand Down
Loading

0 comments on commit b00813c

Please sign in to comment.