From a1bb522ea05ad2171a67fdee33837fe12def4859 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Fri, 12 Feb 2021 18:35:07 +0100 Subject: [PATCH] Move piping stream lines to the log to common --- src/common/logging/common.cpp | 4 --- src/common/logging/common.h | 55 +++++++++++++++++++++++++++++++++ src/plugin/host-process.cpp | 24 ++------------ src/plugin/host-process.h | 12 ------- src/plugin/utils.h | 18 ----------- src/wine-host/bridges/group.cpp | 28 +++-------------- src/wine-host/bridges/group.h | 23 ++------------ 7 files changed, 64 insertions(+), 100 deletions(-) diff --git a/src/common/logging/common.cpp b/src/common/logging/common.cpp index 10fb0354..27cc904e 100644 --- a/src/common/logging/common.cpp +++ b/src/common/logging/common.cpp @@ -16,10 +16,6 @@ #include "common.h" -#ifdef __WINE__ -#include "../wine-host/boost-fix.h" -#endif - #include #include diff --git a/src/common/logging/common.h b/src/common/logging/common.h index 36df5dc4..608c43ab 100644 --- a/src/common/logging/common.h +++ b/src/common/logging/common.h @@ -20,6 +20,31 @@ #include #include +#ifdef __WINE__ +#include "../wine-host/boost-fix.h" +#endif + +#include +#include +#include + +/** + * Boost 1.72 was released with a known breaking bug caused by a missing + * typedef: https://github.com/boostorg/process/issues/116. + * + * Luckily this is easy to fix since it's not really possible to downgrade Boost + * as it would break other applications. + * + * Check if this is still needed for other distros after Arch starts packaging + * Boost 1.73. + */ +class patched_async_pipe : public boost::process::async_pipe { + public: + using boost::process::async_pipe::async_pipe; + + typedef typename handle_type::executor_type executor_type; +}; + /** * Super basic logging facility meant for debugging malfunctioning VST * plugins. This is also used to redirect the output of the Wine process @@ -112,6 +137,36 @@ class Logger { */ void log_trace(const std::string& message); + /** + * Write output from an async pipe to the log on a line by line basis. + * Useful for logging the Wine process's STDOUT and STDERR streams. + * + * @param pipe Some Boost.Asio stream that can be read from. Probably either + * `patched_async_pipe` or a stream descriptor. + * @param buffer The buffer that will be used to read from `pipe`. + * @param prefix Text to prepend to the line before writing to the log. + */ + template + void async_log_pipe_lines(T& pipe, + boost::asio::streambuf& buffer, + std::string prefix = "") { + boost::asio::async_read_until( + pipe, buffer, '\n', + [&, prefix](const boost::system::error_code& error, size_t) { + // When we get an error code then that likely means that the + // pipe has been clsoed and we have reached the end of the file + if (error.failed()) { + return; + } + + std::string line; + std::getline(std::istream(&buffer), line); + log(prefix + line); + + async_log_pipe_lines(pipe, buffer, prefix); + }); + } + /** * The verbosity level of this logger instance. Based on this certain * messages may or may not be shown. diff --git a/src/plugin/host-process.cpp b/src/plugin/host-process.cpp index 2ccb4f62..621ac182 100644 --- a/src/plugin/host-process.cpp +++ b/src/plugin/host-process.cpp @@ -61,28 +61,8 @@ HostProcess::HostProcess(boost::asio::io_context& io_context, Logger& logger) // Print the Wine host's STDOUT and STDERR streams to the log file. This // should be done before trying to accept the sockets as otherwise we will // miss all output. - async_log_pipe_lines(stdout_pipe, stdout_buffer, "[Wine STDOUT] "); - async_log_pipe_lines(stderr_pipe, stderr_buffer, "[Wine STDERR] "); -} - -void HostProcess::async_log_pipe_lines(patched_async_pipe& pipe, - boost::asio::streambuf& buffer, - std::string prefix) { - boost::asio::async_read_until( - pipe, buffer, '\n', - [&, prefix](const boost::system::error_code& error, size_t) { - // When we get an error code then that likely means that the pipe - // has been clsoed and we have reached the end of the file - if (error.failed()) { - return; - } - - std::string line; - std::getline(std::istream(&buffer), line); - logger.log(prefix + line); - - async_log_pipe_lines(pipe, buffer, prefix); - }); + logger.async_log_pipe_lines(stdout_pipe, stdout_buffer, "[Wine STDOUT] "); + logger.async_log_pipe_lines(stderr_pipe, stderr_buffer, "[Wine STDERR] "); } IndividualHost::IndividualHost(boost::asio::io_context& io_context, diff --git a/src/plugin/host-process.h b/src/plugin/host-process.h index 544977ab..1868be9f 100644 --- a/src/plugin/host-process.h +++ b/src/plugin/host-process.h @@ -81,18 +81,6 @@ class HostProcess { patched_async_pipe stderr_pipe; private: - /** - * Write output from an async pipe to the log on a line by line basis. - * Useful for logging the Wine process's STDOUT and STDERR streams. - * - * @param pipe The pipe to read from. - * @param buffer The stream buffer to write to. - * @param prefix Text to prepend to the line before writing to the log. - */ - void async_log_pipe_lines(patched_async_pipe& pipe, - boost::asio::streambuf& buffer, - std::string prefix = ""); - /** * The logger the Wine output will be written to. */ diff --git a/src/plugin/utils.h b/src/plugin/utils.h index 34691db8..bdeb0009 100644 --- a/src/plugin/utils.h +++ b/src/plugin/utils.h @@ -18,29 +18,11 @@ #include -#include #include #include "../common/configuration.h" #include "../common/plugins.h" -/** - * Boost 1.72 was released with a known breaking bug caused by a missing - * typedef: https://github.com/boostorg/process/issues/116. - * - * Luckily this is easy to fix since it's not really possible to downgrade Boost - * as it would break other applications. - * - * Check if this is still needed for other distros after Arch starts packaging - * Boost 1.73. - */ -class patched_async_pipe : public boost::process::async_pipe { - public: - using boost::process::async_pipe::async_pipe; - - typedef typename handle_type::executor_type executor_type; -}; - /** * Marker struct for when we use the default Wine prefix. */ diff --git a/src/wine-host/bridges/group.cpp b/src/wine-host/bridges/group.cpp index 2ced9723..3eb6bb3e 100644 --- a/src/wine-host/bridges/group.cpp +++ b/src/wine-host/bridges/group.cpp @@ -19,7 +19,6 @@ #include "../boost-fix.h" #include -#include #include #include @@ -101,8 +100,10 @@ GroupBridge::GroupBridge(boost::filesystem::path group_socket_path) // Write this process's original STDOUT and STDERR streams to the logger // TODO: This works for output generated by plugins, but not for debug // messages generated by wineserver. Is it possible to catch those? - async_log_pipe_lines(stdout_redirect.pipe, stdout_buffer, "[STDOUT] "); - async_log_pipe_lines(stderr_redirect.pipe, stderr_buffer, "[STDERR] "); + logger.async_log_pipe_lines(stdout_redirect.pipe, stdout_buffer, + "[STDOUT] "); + logger.async_log_pipe_lines(stderr_redirect.pipe, stderr_buffer, + "[STDERR] "); stdio_handler = Win32Thread([&]() { // In case a plugin generates a lot of FIXMEs relaying this IO with @@ -300,27 +301,6 @@ void GroupBridge::async_handle_events() { [&]() { return !is_event_loop_inhibited(); }); } -void GroupBridge::async_log_pipe_lines( - boost::asio::posix::stream_descriptor& pipe, - boost::asio::streambuf& buffer, - std::string prefix) { - boost::asio::async_read_until( - pipe, buffer, '\n', - [&, prefix](const boost::system::error_code& error, size_t) { - // When we get an error code then that likely means that the pipe - // has been clsoed and we have reached the end of the file - if (error.failed()) { - return; - } - - std::string line; - std::getline(std::istream(&buffer), line); - logger.log(prefix + line); - - async_log_pipe_lines(pipe, buffer, prefix); - }); -} - boost::asio::local::stream_protocol::acceptor create_acceptor_if_inactive( boost::asio::io_context& io_context, boost::asio::local::stream_protocol::endpoint& endpoint) { diff --git a/src/wine-host/bridges/group.h b/src/wine-host/bridges/group.h index 02421c65..76385af7 100644 --- a/src/wine-host/bridges/group.h +++ b/src/wine-host/bridges/group.h @@ -16,15 +16,12 @@ #pragma once +#include +#include + #include "../boost-fix.h" #include -#include -#include -#include - -#include -#include #include "../common/logging/common.h" #include "../utils.h" @@ -190,20 +187,6 @@ class GroupBridge { */ void async_handle_events(); - /** - * Continuously read from a pipe and write the output to the log file. Used - * with the IO streams captured by `stdout_redirect` and `stderr_redirect`. - * - * TODO: Merge this with `HostProcess::async_log_pipe_lines` - * - * @param pipe The pipe to read from. - * @param buffer The stream buffer to write to. - * @param prefix Text to prepend to the line before writing to the log. - */ - void async_log_pipe_lines(boost::asio::posix::stream_descriptor& pipe, - boost::asio::streambuf& buffer, - std::string prefix); - /** * The logging facility used for this group host process. Since we can't * identify which plugin is generating (debug) output, every line will only