This is an automated email from the ASF dual-hosted git repository.
swebb2066 pushed a commit to branch next_stable
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git
The following commit(s) were added to refs/heads/next_stable by this push:
new de0f0b89 Reduce logging overhead by holding references (#130)
de0f0b89 is described below
commit de0f0b89e72027087f188230da8405c295263074
Author: Stephen Webb <[email protected]>
AuthorDate: Sun Sep 18 09:40:57 2022 +1000
Reduce logging overhead by holding references (#130)
* Do not copy the (const global) thread name into every LoggingEvent
* Ensure thread user name is not always empty
* Detect thread_local support at configure time
---
src/cmake/test-thread-local.cpp | 11 ++++
src/main/cpp/loggingevent.cpp | 63 ++++++++++++++++------
src/main/include/CMakeLists.txt | 26 +++++++--
.../include/log4cxx/private/log4cxx_private.h.in | 11 +---
src/main/include/log4cxx/spi/loggingevent.h | 4 +-
src/test/cpp/helpers/timezonetestcase.cpp | 2 -
6 files changed, 81 insertions(+), 36 deletions(-)
diff --git a/src/cmake/test-thread-local.cpp b/src/cmake/test-thread-local.cpp
new file mode 100644
index 00000000..9a8ba961
--- /dev/null
+++ b/src/cmake/test-thread-local.cpp
@@ -0,0 +1,11 @@
+#include <string>
+
+std::string& getCurrentThreadVar()
+{
+ thread_local std::string thread_id_string;
+ return thread_id_string;
+}
+
+int main(){
+ getCurrentThreadVar() = "name";
+}
diff --git a/src/main/cpp/loggingevent.cpp b/src/main/cpp/loggingevent.cpp
index b652e7fd..8adcd0e6 100644
--- a/src/main/cpp/loggingevent.cpp
+++ b/src/main/cpp/loggingevent.cpp
@@ -51,7 +51,9 @@ struct LoggingEvent::LoggingEventPrivate
ndcLookupRequired(true),
mdcCopyLookupRequired(true),
timeStamp(0),
- locationInfo()
+ locationInfo(),
+ threadName(getCurrentThreadName()),
+ threadUserName(getCurrentThreadUserName())
{
}
@@ -68,7 +70,10 @@ struct LoggingEvent::LoggingEventPrivate
message(message1),
timeStamp(apr_time_now()),
locationInfo(locationInfo1),
- threadName(getCurrentThreadName()) {}
+ threadName(getCurrentThreadName()),
+ threadUserName(getCurrentThreadUserName())
+ {
+ }
~LoggingEventPrivate()
{
@@ -125,14 +130,14 @@ struct LoggingEvent::LoggingEventPrivate
/** The identifier of thread in which this logging event
was generated.
*/
- const LogString threadName;
+ const LogString& threadName;
/**
* The user-specified name of the thread(on a per-platform basis).
* This is set using a method such as pthread_setname_np on POSIX
* systems or SetThreadDescription on Windows.
*/
- const LogString threadUserName;
+ const LogString& threadUserName;
};
IMPLEMENT_LOG4CXX_OBJECT(LoggingEvent)
@@ -297,40 +302,64 @@ LoggingEvent::KeySet LoggingEvent::getPropertyKeySet()
const
}
-const LogString LoggingEvent::getCurrentThreadName()
+const LogString& LoggingEvent::getCurrentThreadName()
{
-#if APR_HAS_THREADS
- LOG4CXX_THREAD_LOCAL LogString thread_name;
+#if defined(_WIN32)
+ using ThreadIdType = DWORD;
+ ThreadIdType threadId = GetCurrentThreadId();
+#elif APR_HAS_THREADS
+ using ThreadIdType = apr_os_thread_t;
+ ThreadIdType threadId = apr_os_thread_current();
+#else
+ using ThreadIdType = int;
+ ThreadIdType threadId = 0;
+#endif
- if ( thread_name.size() )
+#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;
+#endif
+ if ( !thread_id_string.empty() )
{
- return thread_name;
+ return thread_id_string;
}
+#if APR_HAS_THREADS
#if defined(_WIN32)
char result[20];
- DWORD threadId = GetCurrentThreadId();
apr_snprintf(result, sizeof(result), LOG4CXX_WIN32_THREAD_FMTSPEC,
threadId);
#else
// apr_os_thread_t encoded in HEX takes needs as many characters
// as two times the size of the type, plus an additional null byte.
char result[sizeof(apr_os_thread_t) * 3 + 10];
- apr_os_thread_t threadId = apr_os_thread_current();
apr_snprintf(result, sizeof(result), LOG4CXX_APR_THREAD_FMTSPEC,
(void*) &threadId);
#endif /* _WIN32 */
- log4cxx::helpers::Transcoder::decode(reinterpret_cast<const
char*>(result), thread_name);
+ log4cxx::helpers::Transcoder::decode(reinterpret_cast<const
char*>(result), thread_id_string);
- return thread_name;
#else
- return LOG4CXX_STR("0x00000000");
+ thread_id_string = LOG4CXX_STR("0x00000000");
#endif /* APR_HAS_THREADS */
+ return thread_id_string;
}
-const LogString LoggingEvent::getCurrentThreadUserName()
+const LogString& LoggingEvent::getCurrentThreadUserName()
{
- LOG4CXX_THREAD_LOCAL LogString thread_name;
- if( thread_name.size() ){
+#if LOG4CXX_HAS_THREAD_LOCAL
+ thread_local LogString thread_name;
+#else
+ static LogString thread_name = LOG4CXX_STR("(noname)");
+#endif
+ if( !thread_name.empty() ){
return thread_name;
}
diff --git a/src/main/include/CMakeLists.txt b/src/main/include/CMakeLists.txt
index d21ecdac..a2558309 100644
--- a/src/main/include/CMakeLists.txt
+++ b/src/main/include/CMakeLists.txt
@@ -108,6 +108,10 @@ CHECK_FUNCTION_EXISTS(wcstombs HAS_WCSTOMBS)
CHECK_FUNCTION_EXISTS(fwide HAS_FWIDE)
CHECK_LIBRARY_EXISTS(esmtp smtp_create_session "" HAS_LIBESMTP)
CHECK_FUNCTION_EXISTS(syslog HAS_SYSLOG)
+try_compile(HAS_THREAD_LOCAL "${CMAKE_BINARY_DIR}/thread-local-test"
+ "${LOG4CXX_SOURCE_DIR}/src/cmake/test-thread-local.cpp"
+ CXX_STANDARD 11
+ )
if(UNIX)
set(CMAKE_REQUIRED_LIBRARIES "pthread")
CHECK_SYMBOL_EXISTS(pthread_sigmask "signal.h" HAS_PTHREAD_SIGMASK)
@@ -131,16 +135,28 @@ if(WIN32)
CHECK_SYMBOL_EXISTS(GetThreadDescription "windows.h;processthreadsapi.h"
HAS_GETTHREADDESCRIPTION)
endif(WIN32)
-foreach(varName HAS_STD_LOCALE HAS_ODBC HAS_MBSRTOWCS HAS_WCSTOMBS
HAS_FWIDE HAS_LIBESMTP HAS_SYSLOG HAS_PTHREAD_SIGMASK HAS_PTHREAD_SETNAME
HAS_PTHREAD_GETNAME HAS_SETTHREADDESCRIPTION HAS_GETTHREADDESCRIPTION)
+foreach(varName
+ HAS_THREAD_LOCAL
+ HAS_STD_LOCALE
+ HAS_ODBC
+ HAS_MBSRTOWCS
+ HAS_WCSTOMBS
+ HAS_FWIDE
+ HAS_LIBESMTP
+ HAS_SYSLOG
+ HAS_PTHREAD_SIGMASK
+ HAS_PTHREAD_SETNAME
+ HAS_PTHREAD_GETNAME
+ HAS_SETTHREADDESCRIPTION
+ HAS_GETTHREADDESCRIPTION
+ )
if(${varName} EQUAL 0)
continue()
elseif(${varName} EQUAL 1)
continue()
- elseif("${varName}" STREQUAL "ON")
+ elseif("${varName}" STREQUAL "ON" OR "${varName}" STREQUAL "TRUE")
set(${varName} 1 )
- elseif("${varName}" STREQUAL "OFF")
- set(${varName} 0 )
- else()
+ else()
set(${varName} 0 )
endif()
endforeach()
diff --git a/src/main/include/log4cxx/private/log4cxx_private.h.in
b/src/main/include/log4cxx/private/log4cxx_private.h.in
index 55c6844e..9eb5ec23 100644
--- a/src/main/include/log4cxx/private/log4cxx_private.h.in
+++ b/src/main/include/log4cxx/private/log4cxx_private.h.in
@@ -62,15 +62,6 @@
#define LOG4CXX_HAS_PTHREAD_GETNAME @HAS_PTHREAD_GETNAME@
#define LOG4CXX_HAS_SETTHREADDESCRIPTION @HAS_SETTHREADDESCRIPTION@
#define LOG4CXX_HAS_GETTHREADDESCRIPTION @HAS_GETTHREADDESCRIPTION@
-
-#ifdef __BORLANDC__
-/*
- * embarcadero/RAD Studio compilers don't support thread_local:
- *
http://docwiki.embarcadero.com/RADStudio/Sydney/en/Modern_C%2B%2B_Language_Features_Compliance_Status
- */
-#define LOG4CXX_THREAD_LOCAL
-#else
-#define LOG4CXX_THREAD_LOCAL thread_local
-#endif
+#define LOG4CXX_HAS_THREAD_LOCAL @HAS_THREAD_LOCAL@
#endif
diff --git a/src/main/include/log4cxx/spi/loggingevent.h
b/src/main/include/log4cxx/spi/loggingevent.h
index d036f40b..55816aef 100644
--- a/src/main/include/log4cxx/spi/loggingevent.h
+++ b/src/main/include/log4cxx/spi/loggingevent.h
@@ -182,8 +182,8 @@ class LOG4CXX_EXPORT LoggingEvent :
//
LoggingEvent(const LoggingEvent&);
LoggingEvent& operator=(const LoggingEvent&);
- static const LogString getCurrentThreadName();
- static const LogString getCurrentThreadUserName();
+ static const LogString& getCurrentThreadName();
+ static const LogString& getCurrentThreadUserName();
};
diff --git a/src/test/cpp/helpers/timezonetestcase.cpp
b/src/test/cpp/helpers/timezonetestcase.cpp
index cdbe58af..c15200a0 100644
--- a/src/test/cpp/helpers/timezonetestcase.cpp
+++ b/src/test/cpp/helpers/timezonetestcase.cpp
@@ -38,9 +38,7 @@ LOGUNIT_CLASS(TimeZoneTestCase)
LOGUNIT_TEST_SUITE(TimeZoneTestCase);
LOGUNIT_TEST(test1);
LOGUNIT_TEST(test2);
-#if !defined(__BORLANDC__)
LOGUNIT_TEST(test3);
-#endif
LOGUNIT_TEST(test4);
LOGUNIT_TEST(test5);
LOGUNIT_TEST(test6);