diff --git a/configure.ac b/configure.ac index 4f9ce54b..55d00111 100644 --- a/configure.ac +++ b/configure.ac @@ -254,6 +254,21 @@ std::atomic_store(&a, p); [have_atomic_std_shared_ptr=no AC_MSG_RESULT([no])]) +# Check that thread_local storage specifier is available +AC_MSG_CHECKING([whether thread_local storage class specifier is available.]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM( +, +[[ +thread_local int a = 0; +(void)a; +]])], + [AC_DEFINE([HAVE_THREAD_LOCAL], [1], + [Define to 1 if you have thread_local storage specifier.]) + have_thread_local=yes + AC_MSG_RESULT([yes])], + [have_Thread_local=no + AC_MSG_RESULT([no])]) + CXXFLAGS=$save_CXXFLAGS AC_LANG_POP() diff --git a/src/shrpx.cc b/src/shrpx.cc index f2219ba9..668fa881 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -3723,7 +3723,7 @@ int main(int argc, char **argv) { LOG(NOTICE) << "Shutdown momentarily"; - delete log_config(); + delete_log_config(); return 0; } diff --git a/src/shrpx_log_config.cc b/src/shrpx_log_config.cc index d5d08170..57e97912 100644 --- a/src/shrpx_log_config.cc +++ b/src/shrpx_log_config.cc @@ -33,12 +33,24 @@ LogConfig::LogConfig() : accesslog_fd(-1), errorlog_fd(-1), errorlog_tty(false) {} #ifndef NOTHREADS -static pthread_key_t lckey; -static pthread_once_t lckey_once = PTHREAD_ONCE_INIT; +#ifdef HAVE_THREAD_LOCAL +namespace { +thread_local std::unique_ptr config = make_unique(); +} // namespace -static void make_key(void) { pthread_key_create(&lckey, NULL); } +LogConfig *log_config() { return config.get(); } +void delete_log_config() {} +#else // !HAVE_THREAD_LOCAL +namespace { +pthread_key_t lckey; +pthread_once_t lckey_once = PTHREAD_ONCE_INIT; +} // namespace -LogConfig *log_config(void) { +namespace { +void make_key() { pthread_key_create(&lckey, NULL); } +} // namespace + +LogConfig *log_config() { pthread_once(&lckey_once, make_key); LogConfig *config = (LogConfig *)pthread_getspecific(lckey); if (!config) { @@ -47,9 +59,17 @@ LogConfig *log_config(void) { } return config; } -#else -static LogConfig *config = new LogConfig(); -LogConfig *log_config(void) { return config; } + +void delete_log_config() { delete log_config(); } +#endif // !HAVE_THREAD_LOCAL +#else // NOTHREADS +namespace { +std::unique_ptr config = make_unique(); +} // namespace + +LogConfig *log_config() { return config.get(); } + +void delete_log_config() {} #endif // NOTHREADS void LogConfig::update_tstamp( diff --git a/src/shrpx_log_config.h b/src/shrpx_log_config.h index 4e3bc5df..2f37f602 100644 --- a/src/shrpx_log_config.h +++ b/src/shrpx_log_config.h @@ -54,7 +54,10 @@ struct LogConfig { // We need LogConfig per thread to avoid data race around opening file // descriptor for log files. -extern LogConfig *log_config(void); +LogConfig *log_config(); + +// Deletes log_config +void delete_log_config(); } // namespace shrpx