From 574501f44506a866ab25d85e483acdef30d257f9 Mon Sep 17 00:00:00 2001 From: Gabi Melman Date: Sun, 10 Nov 2024 23:24:22 +0200 Subject: [PATCH 1/3] Wincolor sink to use regular mutex --- .gitignore | 3 + include/spdlog/sinks/wincolor_sink-inl.h | 79 ++++++++++-------------- include/spdlog/sinks/wincolor_sink.h | 42 ++++++------- src/color_sinks.cpp | 12 ++-- 4 files changed, 59 insertions(+), 77 deletions(-) diff --git a/.gitignore b/.gitignore index 25f272c9..d52dc0b9 100644 --- a/.gitignore +++ b/.gitignore @@ -96,3 +96,6 @@ cmake-build-*/ /.vs /out/build /CMakeSettings.json +/build-2019/x64-Debug-vs2019 +/fmt +/src/fmt diff --git a/include/spdlog/sinks/wincolor_sink-inl.h b/include/spdlog/sinks/wincolor_sink-inl.h index 696db566..7d25ba1f 100644 --- a/include/spdlog/sinks/wincolor_sink-inl.h +++ b/include/spdlog/sinks/wincolor_sink-inl.h @@ -15,11 +15,9 @@ namespace spdlog { namespace sinks { -template -SPDLOG_INLINE wincolor_sink::wincolor_sink(void *out_handle, color_mode mode) - : out_handle_(out_handle), - mutex_(ConsoleMutex::mutex()), - formatter_(details::make_unique()) { +template +SPDLOG_INLINE wincolor_sink::wincolor_sink(void *out_handle, color_mode mode) + : out_handle_(out_handle) { set_color_mode_impl(mode); // set level colors colors_[level::trace] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; // white @@ -34,30 +32,28 @@ SPDLOG_INLINE wincolor_sink::wincolor_sink(void *out_handle, color colors_[level::off] = 0; } -template -SPDLOG_INLINE wincolor_sink::~wincolor_sink() { +template +SPDLOG_INLINE wincolor_sink::~wincolor_sink() { this->flush(); } // change the color for the given level -template -void SPDLOG_INLINE wincolor_sink::set_color(level::level_enum level, +template +void SPDLOG_INLINE wincolor_sink::set_color(level::level_enum level, std::uint16_t color) { - std::lock_guard lock(mutex_); + std::lock_guard lock(base_t::mutex_); colors_[static_cast(level)] = color; } -template -void SPDLOG_INLINE wincolor_sink::log(const details::log_msg &msg) { +template +void SPDLOG_INLINE wincolor_sink::sink_it_(const details::log_msg &msg) { if (out_handle_ == nullptr || out_handle_ == INVALID_HANDLE_VALUE) { return; - } - - std::lock_guard lock(mutex_); + } msg.color_range_start = 0; msg.color_range_end = 0; memory_buf_t formatted; - formatter_->format(msg, formatted); + base_t::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); @@ -74,32 +70,19 @@ void SPDLOG_INLINE wincolor_sink::log(const details::log_msg &msg) } } -template -void SPDLOG_INLINE wincolor_sink::flush() { +template +void SPDLOG_INLINE wincolor_sink::flush_() { // windows console always flushed? } -template -void SPDLOG_INLINE wincolor_sink::set_pattern(const std::string &pattern) { - std::lock_guard lock(mutex_); - formatter_ = std::unique_ptr(new pattern_formatter(pattern)); -} - -template -void SPDLOG_INLINE -wincolor_sink::set_formatter(std::unique_ptr sink_formatter) { - std::lock_guard lock(mutex_); - formatter_ = std::move(sink_formatter); -} - -template -void SPDLOG_INLINE wincolor_sink::set_color_mode(color_mode mode) { - std::lock_guard lock(mutex_); +template +void SPDLOG_INLINE wincolor_sink::set_color_mode(color_mode mode) { + std::lock_guard lock(base_t::mutex_); set_color_mode_impl(mode); } -template -void SPDLOG_INLINE wincolor_sink::set_color_mode_impl(color_mode mode) { +template +void SPDLOG_INLINE wincolor_sink::set_color_mode_impl(color_mode mode) { if (mode == color_mode::automatic) { // should do colors only if out_handle_ points to actual console. DWORD console_mode; @@ -111,9 +94,9 @@ void SPDLOG_INLINE wincolor_sink::set_color_mode_impl(color_mode m } // set foreground color and return the orig console attributes (for resetting later) -template +template std::uint16_t SPDLOG_INLINE -wincolor_sink::set_foreground_color_(std::uint16_t attribs) { +wincolor_sink::set_foreground_color_(std::uint16_t attribs) { CONSOLE_SCREEN_BUFFER_INFO orig_buffer_info; if (!::GetConsoleScreenBufferInfo(static_cast(out_handle_), &orig_buffer_info)) { // just return white if failed getting console info @@ -129,8 +112,8 @@ wincolor_sink::set_foreground_color_(std::uint16_t attribs) { } // print a range of formatted message to console -template -void SPDLOG_INLINE wincolor_sink::print_range_(const memory_buf_t &formatted, +template +void SPDLOG_INLINE wincolor_sink::print_range_(const memory_buf_t &formatted, size_t start, size_t end) { if (end > start) { @@ -150,8 +133,8 @@ void SPDLOG_INLINE wincolor_sink::print_range_(const memory_buf_t } } -template -void SPDLOG_INLINE wincolor_sink::write_to_file_(const memory_buf_t &formatted) { +template +void SPDLOG_INLINE wincolor_sink::write_to_file_(const memory_buf_t &formatted) { auto size = static_cast(formatted.size()); DWORD bytes_written = 0; auto ignored = ::WriteFile(static_cast(out_handle_), formatted.data(), size, @@ -160,13 +143,13 @@ void SPDLOG_INLINE wincolor_sink::write_to_file_(const memory_buf_ } // wincolor_stdout_sink -template -SPDLOG_INLINE wincolor_stdout_sink::wincolor_stdout_sink(color_mode mode) - : wincolor_sink(::GetStdHandle(STD_OUTPUT_HANDLE), mode) {} +template +SPDLOG_INLINE wincolor_stdout_sink::wincolor_stdout_sink(color_mode mode) + : wincolor_sink(::GetStdHandle(STD_OUTPUT_HANDLE), mode) {} // wincolor_stderr_sink -template -SPDLOG_INLINE wincolor_stderr_sink::wincolor_stderr_sink(color_mode mode) - : wincolor_sink(::GetStdHandle(STD_ERROR_HANDLE), mode) {} +template +SPDLOG_INLINE wincolor_stderr_sink::wincolor_stderr_sink(color_mode mode) + : wincolor_sink(::GetStdHandle(STD_ERROR_HANDLE), mode) {} } // namespace sinks } // namespace spdlog diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h index 8ba594cc..9b9dfc24 100644 --- a/include/spdlog/sinks/wincolor_sink.h +++ b/include/spdlog/sinks/wincolor_sink.h @@ -4,9 +4,8 @@ #pragma once #include -#include +#include #include -#include #include #include @@ -20,9 +19,10 @@ namespace sinks { * Windows color console sink. Uses WriteConsoleA to write to the console with * colors */ -template -class wincolor_sink : public sink { +template +class wincolor_sink : public base_sink { public: + using base_t = base_sink; wincolor_sink(void *out_handle, color_mode mode); ~wincolor_sink() override; @@ -30,21 +30,17 @@ public: wincolor_sink &operator=(const wincolor_sink &other) = delete; // change the color for the given level - void set_color(level::level_enum level, std::uint16_t color); - void log(const details::log_msg &msg) final override; - void flush() final override; - void set_pattern(const std::string &pattern) override final; - void set_formatter(std::unique_ptr sink_formatter) override final; + void set_color(level::level_enum level, std::uint16_t color); void set_color_mode(color_mode mode); -protected: - using mutex_t = typename ConsoleMutex::mutex_t; - void *out_handle_; - mutex_t &mutex_; - bool should_do_colors_; - std::unique_ptr formatter_; +protected: + void *out_handle_; + bool should_do_colors_; std::array colors_; + void sink_it_(const details::log_msg &msg) final override; + void flush_() final override; + // set foreground color and return the orig console attributes (for resetting later) std::uint16_t set_foreground_color_(std::uint16_t attribs); @@ -57,23 +53,23 @@ protected: void set_color_mode_impl(color_mode mode); }; -template -class wincolor_stdout_sink : public wincolor_sink { +template +class wincolor_stdout_sink : public wincolor_sink { public: explicit wincolor_stdout_sink(color_mode mode = color_mode::automatic); }; -template -class wincolor_stderr_sink : public wincolor_sink { +template +class wincolor_stderr_sink : public wincolor_sink { public: explicit wincolor_stderr_sink(color_mode mode = color_mode::automatic); }; -using wincolor_stdout_sink_mt = wincolor_stdout_sink; -using wincolor_stdout_sink_st = wincolor_stdout_sink; +using wincolor_stdout_sink_mt = wincolor_stdout_sink; +using wincolor_stdout_sink_st = wincolor_stdout_sink; -using wincolor_stderr_sink_mt = wincolor_stderr_sink; -using wincolor_stderr_sink_st = wincolor_stderr_sink; +using wincolor_stderr_sink_mt = wincolor_stderr_sink; +using wincolor_stderr_sink_st = wincolor_stderr_sink; } // namespace sinks } // namespace spdlog diff --git a/src/color_sinks.cpp b/src/color_sinks.cpp index 21ec1efc..3c1a7354 100644 --- a/src/color_sinks.cpp +++ b/src/color_sinks.cpp @@ -14,12 +14,12 @@ // #ifdef _WIN32 #include -template class SPDLOG_API spdlog::sinks::wincolor_sink; -template class SPDLOG_API spdlog::sinks::wincolor_sink; -template class SPDLOG_API spdlog::sinks::wincolor_stdout_sink; -template class SPDLOG_API spdlog::sinks::wincolor_stdout_sink; -template class SPDLOG_API spdlog::sinks::wincolor_stderr_sink; -template class SPDLOG_API spdlog::sinks::wincolor_stderr_sink; +template class SPDLOG_API spdlog::sinks::wincolor_sink; +template class SPDLOG_API spdlog::sinks::wincolor_sink; +template class SPDLOG_API spdlog::sinks::wincolor_stdout_sink; +template class SPDLOG_API spdlog::sinks::wincolor_stdout_sink; +template class SPDLOG_API spdlog::sinks::wincolor_stderr_sink; +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; From bfe2116191ca86448710b2de385c8f3283ffacc0 Mon Sep 17 00:00:00 2001 From: Gabi Melman Date: Sun, 10 Nov 2024 23:26:27 +0200 Subject: [PATCH 2/3] Remove unused include from wincolor sink --- include/spdlog/sinks/wincolor_sink.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h index 9b9dfc24..99a12a1e 100644 --- a/include/spdlog/sinks/wincolor_sink.h +++ b/include/spdlog/sinks/wincolor_sink.h @@ -9,9 +9,7 @@ #include #include -#include #include -#include namespace spdlog { namespace sinks { From 3c4b1ceb3673ab4e7a3937dbd5ff535f515911ef Mon Sep 17 00:00:00 2001 From: Gabi Melman Date: Sun, 10 Nov 2024 23:44:15 +0200 Subject: [PATCH 3/3] Add consolute mutex support to wincolor sink --- include/spdlog/sinks/wincolor_sink-inl.h | 12 +++++++++++- include/spdlog/sinks/wincolor_sink.h | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/spdlog/sinks/wincolor_sink-inl.h b/include/spdlog/sinks/wincolor_sink-inl.h index 7d25ba1f..7f59c763 100644 --- a/include/spdlog/sinks/wincolor_sink-inl.h +++ b/include/spdlog/sinks/wincolor_sink-inl.h @@ -17,7 +17,7 @@ namespace spdlog { namespace sinks { template SPDLOG_INLINE wincolor_sink::wincolor_sink(void *out_handle, color_mode mode) - : out_handle_(out_handle) { + : out_handle_(out_handle), console_mutex_(nullptr) { set_color_mode_impl(mode); // set level colors colors_[level::trace] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; // white @@ -45,6 +45,12 @@ void SPDLOG_INLINE wincolor_sink::set_color(level::level_enum level, colors_[static_cast(level)] = color; } +template +void SPDLOG_INLINE wincolor_sink::set_console_mutex(std::mutex* mutex) { + std::lock_guard lock(base_t::mutex_); + console_mutex_ = mutex; +} + template void SPDLOG_INLINE wincolor_sink::sink_it_(const details::log_msg &msg) { if (out_handle_ == nullptr || out_handle_ == INVALID_HANDLE_VALUE) { @@ -54,6 +60,10 @@ void SPDLOG_INLINE wincolor_sink::sink_it_(const details::log_msg &msg) { msg.color_range_end = 0; memory_buf_t formatted; base_t::formatter_->format(msg, formatted); + + auto console_lock = console_mutex_ != nullptr ? std::unique_lock(*console_mutex_) + : std::unique_lock(); + if (should_do_colors_ && msg.color_range_end > msg.color_range_start) { // before color range print_range_(formatted, 0, msg.color_range_start); diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h index 99a12a1e..c133bd18 100644 --- a/include/spdlog/sinks/wincolor_sink.h +++ b/include/spdlog/sinks/wincolor_sink.h @@ -30,11 +30,13 @@ public: // change the color for the given level void set_color(level::level_enum level, std::uint16_t color); void set_color_mode(color_mode mode); + void set_console_mutex(std::mutex *console_mutex); protected: void *out_handle_; bool should_do_colors_; std::array colors_; + std::mutex *console_mutex_; void sink_it_(const details::log_msg &msg) final override; void flush_() final override;