From 04243db77904a9d735e545a1114e0dd926649ac9 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sun, 6 Aug 2023 18:44:35 +0300 Subject: [PATCH] Synchronize stdout & stderr for logging --- libs/io/include/psemek/io/synchronized.hpp | 15 ++++++ libs/io/source/synchronized.cpp | 60 ++++++++++++++++++++++ libs/sdl2/source/main.cpp | 10 +++- 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 libs/io/include/psemek/io/synchronized.hpp create mode 100644 libs/io/source/synchronized.cpp diff --git a/libs/io/include/psemek/io/synchronized.hpp b/libs/io/include/psemek/io/synchronized.hpp new file mode 100644 index 00000000..60df8257 --- /dev/null +++ b/libs/io/include/psemek/io/synchronized.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include + +#include + +namespace psemek::io +{ + + // Convert a set of output streams to a set of mutually + // synchronized streams: writing to any of the streams + // flushes all the other streams + std::vector> synchronized(std::vector> streams); + +} diff --git a/libs/io/source/synchronized.cpp b/libs/io/source/synchronized.cpp new file mode 100644 index 00000000..0672201f --- /dev/null +++ b/libs/io/source/synchronized.cpp @@ -0,0 +1,60 @@ +#include + +namespace psemek::io +{ + + namespace + { + + struct synchronized_stream_impl + : ostream + { + synchronized_stream_impl(std::shared_ptr stream, std::vector> others) + : stream_(std::move(stream)) + , others_(std::move(others)) + {} + + std::size_t write(char const * p, std::size_t size) override + { + for (auto const & ptr : others_) + if (auto stream = ptr.lock()) + stream->flush(); + return stream_->write(p, size); + } + + void flush() override + { + stream_->flush(); + } + + private: + std::shared_ptr stream_; + std::vector> others_; + }; + + } + + // Convert a set of output streams to a set of mutually + // synchronized streams: writing to any of the streams + // flushes all the other streams + std::vector> synchronized(std::vector> streams) + { + std::vector> shared_streams(streams.size()); + for (std::size_t i = 0; i < streams.size(); ++i) + shared_streams[i] = std::move(streams[i]); + + std::vector> result; + for (std::size_t i = 0; i < streams.size(); ++i) + { + std::vector> others; + for (std::size_t j = 0; j < streams.size(); ++j) + if (i != j) + others.push_back(shared_streams[i]); + + result.push_back(std::make_unique(shared_streams[i], std::move(others))); + } + + return result; + } + +} diff --git a/libs/sdl2/source/main.cpp b/libs/sdl2/source/main.cpp index db692325..dfc702f1 100644 --- a/libs/sdl2/source/main.cpp +++ b/libs/sdl2/source/main.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #undef main @@ -22,8 +23,13 @@ int main(int argc, char ** argv) try log::level const stdio_log_level = log::level::debug; #endif - log::add_sink(log::default_sink(io::std_out(), stdio_log_level, log::level::info)); - log::add_sink(log::default_sink(io::std_err(), log::level::warning, log::level::error)); + std::vector> synchronized_stdout_stderr; + synchronized_stdout_stderr.push_back(io::std_out()); + synchronized_stdout_stderr.push_back(io::std_err()); + synchronized_stdout_stderr = io::synchronized(std::move(synchronized_stdout_stderr)); + + log::add_sink(log::default_sink(std::move(synchronized_stdout_stderr[0]), stdio_log_level, log::level::info)); + log::add_sink(log::default_sink(std::move(synchronized_stdout_stderr[1]), log::level::warning, log::level::error)); log::register_thread("main"); auto const factory = app::make_application_factory();