From 01643a5e6dc3e962cac3f47c00c1e972c76c3de8 Mon Sep 17 00:00:00 2001 From: gabime Date: Sat, 9 Nov 2024 14:18:38 +0200 Subject: [PATCH] Use regular mutex in stdout sinks --- include/spdlog/details/console_globals.h | 28 -------- include/spdlog/details/registry-inl.h | 4 ++ include/spdlog/details/registry.h | 3 + include/spdlog/sinks/ansicolor_sink-inl.h | 84 ++++++++++------------- include/spdlog/sinks/ansicolor_sink.h | 41 +++++------ include/spdlog/sinks/stdout_sinks-inl.h | 51 +++++--------- include/spdlog/sinks/stdout_sinks.h | 35 ++++------ src/color_sinks.cpp | 12 ++-- src/stdout_sinks.cpp | 12 ++-- 9 files changed, 101 insertions(+), 169 deletions(-) delete mode 100644 include/spdlog/details/console_globals.h diff --git a/include/spdlog/details/console_globals.h b/include/spdlog/details/console_globals.h deleted file mode 100644 index 9c552106..00000000 --- a/include/spdlog/details/console_globals.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) - -#pragma once - -#include -#include - -namespace spdlog { -namespace details { - -struct console_mutex { - using mutex_t = std::mutex; - static mutex_t &mutex() { - static mutex_t s_mutex; - return s_mutex; - } -}; - -struct console_nullmutex { - using mutex_t = null_mutex; - static mutex_t &mutex() { - static mutex_t s_mutex; - return s_mutex; - } -}; -} // namespace details -} // namespace spdlog diff --git a/include/spdlog/details/registry-inl.h b/include/spdlog/details/registry-inl.h index f447848e..e09cb180 100644 --- a/include/spdlog/details/registry-inl.h +++ b/include/spdlog/details/registry-inl.h @@ -245,6 +245,10 @@ SPDLOG_INLINE void registry::apply_logger_env_levels(std::shared_ptr new new_logger->set_level(new_level); } +SPDLOG_INLINE std::mutex ®istry::console_mutex() { + return console_mutex_; +} + SPDLOG_INLINE void registry::throw_if_exists_(const std::string &logger_name) { if (loggers_.find(logger_name) != loggers_.end()) { throw_spdlog_ex("logger with name '" + logger_name + "' already exists"); diff --git a/include/spdlog/details/registry.h b/include/spdlog/details/registry.h index 8afcbd6f..f78708cd 100644 --- a/include/spdlog/details/registry.h +++ b/include/spdlog/details/registry.h @@ -99,6 +99,8 @@ public: void apply_logger_env_levels(std::shared_ptr new_logger); + std::mutex& console_mutex(); + private: registry(); ~registry(); @@ -119,6 +121,7 @@ private: std::shared_ptr default_logger_; bool automatic_registration_ = true; size_t backtrace_n_messages_ = 0; + std::mutex console_mutex_; }; } // namespace details diff --git a/include/spdlog/sinks/ansicolor_sink-inl.h b/include/spdlog/sinks/ansicolor_sink-inl.h index 2194f67b..f2ecd1b0 100644 --- a/include/spdlog/sinks/ansicolor_sink-inl.h +++ b/include/spdlog/sinks/ansicolor_sink-inl.h @@ -13,12 +13,9 @@ namespace spdlog { namespace sinks { -template -SPDLOG_INLINE ansicolor_sink::ansicolor_sink(FILE *target_file, color_mode mode) - : target_file_(target_file), - mutex_(ConsoleMutex::mutex()), - formatter_(details::make_unique()) - +template +SPDLOG_INLINE ansicolor_sink::ansicolor_sink(FILE *target_file, color_mode mode) + : target_file_(target_file) { set_color_mode(mode); colors_.at(level::trace) = to_string_(white); @@ -30,22 +27,21 @@ SPDLOG_INLINE ansicolor_sink::ansicolor_sink(FILE *target_file, co colors_.at(level::off) = to_string_(reset); } -template -SPDLOG_INLINE void ansicolor_sink::set_color(level::level_enum color_level, +template +SPDLOG_INLINE void ansicolor_sink::set_color(level::level_enum color_level, string_view_t color) { - std::lock_guard lock(mutex_); + std::lock_guard lock(base_sink::mutex_); colors_.at(static_cast(color_level)) = to_string_(color); } -template -SPDLOG_INLINE void ansicolor_sink::log(const details::log_msg &msg) { +template +SPDLOG_INLINE void ansicolor_sink::sink_it_(const details::log_msg &msg) { // Wrap the originally formatted message in color codes. // If color is not supported in the terminal, log as is instead. - std::lock_guard lock(mutex_); msg.color_range_start = 0; msg.color_range_end = 0; memory_buf_t formatted; - formatter_->format(msg, formatted); + base_sink::formatter_->format(msg, formatted); if (should_do_colors_ && msg.color_range_end > msg.color_range_start) { // before color range print_range_(formatted, 0, msg.color_range_start); @@ -62,74 +58,66 @@ SPDLOG_INLINE void ansicolor_sink::log(const details::log_msg &msg fflush(target_file_); } -template -SPDLOG_INLINE void ansicolor_sink::flush() { - std::lock_guard lock(mutex_); +template +SPDLOG_INLINE void ansicolor_sink::flush_() { fflush(target_file_); } -template -SPDLOG_INLINE void ansicolor_sink::set_pattern(const std::string &pattern) { - std::lock_guard lock(mutex_); - formatter_ = std::unique_ptr(new pattern_formatter(pattern)); -} - -template -SPDLOG_INLINE void ansicolor_sink::set_formatter( - std::unique_ptr sink_formatter) { - std::lock_guard lock(mutex_); - formatter_ = std::move(sink_formatter); -} - -template -SPDLOG_INLINE bool ansicolor_sink::should_color() { +template +SPDLOG_INLINE bool ansicolor_sink::should_color() { return should_do_colors_; } -template -SPDLOG_INLINE void ansicolor_sink::set_color_mode(color_mode mode) { +template +SPDLOG_INLINE void ansicolor_sink::set_color_mode(color_mode mode) { + std::lock_guard lock(base_sink::mutex_); + set_color_mode_(mode); +} + +template +SPDLOG_INLINE void ansicolor_sink::set_color_mode_(color_mode mode) { switch (mode) { case color_mode::always: should_do_colors_ = true; - return; + return; case color_mode::automatic: should_do_colors_ = details::os::in_terminal(target_file_) && details::os::is_color_terminal(); - return; + return; case color_mode::never: should_do_colors_ = false; - return; + return; default: should_do_colors_ = false; } } -template -SPDLOG_INLINE void ansicolor_sink::print_ccode_(const string_view_t &color_code) { +template +SPDLOG_INLINE void ansicolor_sink::print_ccode_(const string_view_t &color_code) { fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_); } -template -SPDLOG_INLINE void ansicolor_sink::print_range_(const memory_buf_t &formatted, +template +SPDLOG_INLINE void ansicolor_sink::print_range_(const memory_buf_t &formatted, size_t start, size_t end) { fwrite(formatted.data() + start, sizeof(char), end - start, target_file_); } -template -SPDLOG_INLINE std::string ansicolor_sink::to_string_(const string_view_t &sv) { +template +SPDLOG_INLINE std::string ansicolor_sink::to_string_(const string_view_t &sv) { return std::string(sv.data(), sv.size()); } // ansicolor_stdout_sink -template -SPDLOG_INLINE ansicolor_stdout_sink::ansicolor_stdout_sink(color_mode mode) - : ansicolor_sink(stdout, mode) {} +template +SPDLOG_INLINE ansicolor_stdout_sink::ansicolor_stdout_sink(color_mode mode) + : ansicolor_sink(stdout, mode) {} // ansicolor_stderr_sink -template -SPDLOG_INLINE ansicolor_stderr_sink::ansicolor_stderr_sink(color_mode mode) - : ansicolor_sink(stderr, mode) {} +template +SPDLOG_INLINE ansicolor_stderr_sink::ansicolor_stderr_sink(color_mode mode) + : ansicolor_sink(stderr, mode) {} } // namespace sinks } // namespace spdlog diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index d0dadd75..bca0d05f 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -3,12 +3,10 @@ #pragma once +#include "base_sink.h" + #include #include -#include -#include -#include -#include #include namespace spdlog { @@ -21,10 +19,9 @@ namespace sinks { * If no color terminal detected, omit the escape codes. */ -template -class ansicolor_sink : public sink { +template +class ansicolor_sink : public base_sink { public: - using mutex_t = typename ConsoleMutex::mutex_t; ansicolor_sink(FILE *target_file, color_mode mode); ~ansicolor_sink() override = default; @@ -37,12 +34,6 @@ public: void set_color(level::level_enum color_level, string_view_t color); void set_color_mode(color_mode mode); bool should_color(); - - void log(const details::log_msg &msg) override; - void flush() override; - void set_pattern(const std::string &pattern) final override; - void set_formatter(std::unique_ptr sink_formatter) override; - // Formatting codes const string_view_t reset = "\033[m"; const string_view_t bold = "\033[1m"; @@ -78,34 +69,36 @@ public: const string_view_t red_bold = "\033[31m\033[1m"; const string_view_t bold_on_red = "\033[1m\033[41m"; -private: +protected: FILE *target_file_; - mutex_t &mutex_; bool should_do_colors_; - std::unique_ptr formatter_; std::array colors_; + + void sink_it_(const details::log_msg &msg) override; + void flush_() override; + void set_color_mode_(color_mode mode); void print_ccode_(const string_view_t &color_code); void print_range_(const memory_buf_t &formatted, size_t start, size_t end); static std::string to_string_(const string_view_t &sv); }; -template -class ansicolor_stdout_sink : public ansicolor_sink { +template +class ansicolor_stdout_sink : public ansicolor_sink { public: explicit ansicolor_stdout_sink(color_mode mode = color_mode::automatic); }; -template -class ansicolor_stderr_sink : public ansicolor_sink { +template +class ansicolor_stderr_sink : public ansicolor_sink { public: explicit ansicolor_stderr_sink(color_mode mode = color_mode::automatic); }; -using ansicolor_stdout_sink_mt = ansicolor_stdout_sink; -using ansicolor_stdout_sink_st = ansicolor_stdout_sink; +using ansicolor_stdout_sink_mt = ansicolor_stdout_sink; +using ansicolor_stdout_sink_st = ansicolor_stdout_sink; -using ansicolor_stderr_sink_mt = ansicolor_stderr_sink; -using ansicolor_stderr_sink_st = ansicolor_stderr_sink; +using ansicolor_stderr_sink_mt = ansicolor_stderr_sink; +using ansicolor_stderr_sink_st = ansicolor_stderr_sink; } // namespace sinks } // namespace spdlog diff --git a/include/spdlog/sinks/stdout_sinks-inl.h b/include/spdlog/sinks/stdout_sinks-inl.h index f98244db..2ed41b92 100644 --- a/include/spdlog/sinks/stdout_sinks-inl.h +++ b/include/spdlog/sinks/stdout_sinks-inl.h @@ -8,7 +8,6 @@ #endif #include -#include #include #ifdef _WIN32 @@ -22,17 +21,15 @@ #include // _get_osfhandle(..) #include // _fileno(..) -#endif // WIN32 +#endif // _WIN32 namespace spdlog { namespace sinks { -template -SPDLOG_INLINE stdout_sink_base::stdout_sink_base(FILE *file) - : mutex_(ConsoleMutex::mutex()), - file_(file), - formatter_(details::make_unique()) { +template +SPDLOG_INLINE stdout_sink_base::stdout_sink_base(FILE *file) + :file_(file) { #ifdef _WIN32 // get windows handle from the FILE* object @@ -47,15 +44,14 @@ SPDLOG_INLINE stdout_sink_base::stdout_sink_base(FILE *file) #endif // WIN32 } -template -SPDLOG_INLINE void stdout_sink_base::log(const details::log_msg &msg) { +template +SPDLOG_INLINE void stdout_sink_base::sink_it_(const details::log_msg &msg) { #ifdef _WIN32 if (handle_ == INVALID_HANDLE_VALUE) { return; } - std::lock_guard lock(mutex_); memory_buf_t formatted; - formatter_->format(msg, formatted); + base_sink::formatter_->format(msg, formatted); auto size = static_cast(formatted.size()); DWORD bytes_written = 0; bool ok = ::WriteFile(handle_, formatted.data(), size, &bytes_written, nullptr) != 0; @@ -64,42 +60,27 @@ SPDLOG_INLINE void stdout_sink_base::log(const details::log_msg &m std::to_string(::GetLastError())); } #else - std::lock_guard lock(mutex_); memory_buf_t formatted; - formatter_->format(msg, formatted); + base_sink::formatter_->format(msg, formatted); ::fwrite(formatted.data(), sizeof(char), formatted.size(), file_); #endif // WIN32 ::fflush(file_); // flush every line to terminal } -template -SPDLOG_INLINE void stdout_sink_base::flush() { - std::lock_guard lock(mutex_); +template +SPDLOG_INLINE void stdout_sink_base::flush_() { fflush(file_); } -template -SPDLOG_INLINE void stdout_sink_base::set_pattern(const std::string &pattern) { - std::lock_guard lock(mutex_); - formatter_ = std::unique_ptr(new pattern_formatter(pattern)); -} - -template -SPDLOG_INLINE void stdout_sink_base::set_formatter( - std::unique_ptr sink_formatter) { - std::lock_guard lock(mutex_); - formatter_ = std::move(sink_formatter); -} - // stdout sink -template -SPDLOG_INLINE stdout_sink::stdout_sink() - : stdout_sink_base(stdout) {} +template +SPDLOG_INLINE stdout_sink::stdout_sink() + : stdout_sink_base(stdout) {} // stderr sink -template -SPDLOG_INLINE stderr_sink::stderr_sink() - : stdout_sink_base(stderr) {} +template +SPDLOG_INLINE stderr_sink::stderr_sink() + : stdout_sink_base(stderr) {} } // namespace sinks diff --git a/include/spdlog/sinks/stdout_sinks.h b/include/spdlog/sinks/stdout_sinks.h index 6ef09968..0f6188eb 100644 --- a/include/spdlog/sinks/stdout_sinks.h +++ b/include/spdlog/sinks/stdout_sinks.h @@ -4,9 +4,8 @@ #pragma once #include -#include #include -#include +#include #ifdef _WIN32 #include @@ -16,10 +15,9 @@ namespace spdlog { namespace sinks { -template -class stdout_sink_base : public sink { +template +class stdout_sink_base : public base_sink { public: - using mutex_t = typename ConsoleMutex::mutex_t; explicit stdout_sink_base(FILE *file); ~stdout_sink_base() override = default; @@ -28,39 +26,32 @@ public: stdout_sink_base &operator=(const stdout_sink_base &other) = delete; stdout_sink_base &operator=(stdout_sink_base &&other) = delete; - - void log(const details::log_msg &msg) override; - void flush() override; - void set_pattern(const std::string &pattern) override; - - void set_formatter(std::unique_ptr sink_formatter) override; - protected: - mutex_t &mutex_; + void sink_it_(const details::log_msg &msg) override; + void flush_() override; FILE *file_; - std::unique_ptr formatter_; #ifdef _WIN32 HANDLE handle_; #endif // WIN32 }; -template -class stdout_sink : public stdout_sink_base { +template +class stdout_sink : public stdout_sink_base { public: stdout_sink(); }; -template -class stderr_sink : public stdout_sink_base { +template +class stderr_sink : public stdout_sink_base { public: stderr_sink(); }; -using stdout_sink_mt = stdout_sink; -using stdout_sink_st = stdout_sink; +using stdout_sink_mt = stdout_sink; +using stdout_sink_st = stdout_sink; -using stderr_sink_mt = stderr_sink; -using stderr_sink_st = stderr_sink; +using stderr_sink_mt = stderr_sink; +using stderr_sink_st = stderr_sink; } // namespace sinks diff --git a/src/color_sinks.cpp b/src/color_sinks.cpp index c44db197..21ec1efc 100644 --- a/src/color_sinks.cpp +++ b/src/color_sinks.cpp @@ -22,12 +22,12 @@ template class SPDLOG_API spdlog::sinks::wincolor_stderr_sink; #else #include "spdlog/sinks/ansicolor_sink-inl.h" -template class SPDLOG_API spdlog::sinks::ansicolor_sink; -template class SPDLOG_API spdlog::sinks::ansicolor_sink; -template class SPDLOG_API spdlog::sinks::ansicolor_stdout_sink; -template class SPDLOG_API spdlog::sinks::ansicolor_stdout_sink; -template class SPDLOG_API spdlog::sinks::ansicolor_stderr_sink; -template class SPDLOG_API spdlog::sinks::ansicolor_stderr_sink; +template class SPDLOG_API spdlog::sinks::ansicolor_sink; +template class SPDLOG_API spdlog::sinks::ansicolor_sink; +template class SPDLOG_API spdlog::sinks::ansicolor_stdout_sink; +template class SPDLOG_API spdlog::sinks::ansicolor_stdout_sink; +template class SPDLOG_API spdlog::sinks::ansicolor_stderr_sink; +template class SPDLOG_API spdlog::sinks::ansicolor_stderr_sink; #endif // factory methods for color loggers diff --git a/src/stdout_sinks.cpp b/src/stdout_sinks.cpp index bf4cfae2..5d6a8aef 100644 --- a/src/stdout_sinks.cpp +++ b/src/stdout_sinks.cpp @@ -11,12 +11,12 @@ #include #include -template class SPDLOG_API spdlog::sinks::stdout_sink_base; -template class SPDLOG_API spdlog::sinks::stdout_sink_base; -template class SPDLOG_API spdlog::sinks::stdout_sink; -template class SPDLOG_API spdlog::sinks::stdout_sink; -template class SPDLOG_API spdlog::sinks::stderr_sink; -template class SPDLOG_API spdlog::sinks::stderr_sink; +template class SPDLOG_API spdlog::sinks::stdout_sink_base; +template class SPDLOG_API spdlog::sinks::stdout_sink_base; +template class SPDLOG_API spdlog::sinks::stdout_sink; +template class SPDLOG_API spdlog::sinks::stdout_sink; +template class SPDLOG_API spdlog::sinks::stderr_sink; +template class SPDLOG_API spdlog::sinks::stderr_sink; template SPDLOG_API std::shared_ptr spdlog::stdout_logger_mt(const std::string &logger_name);