From 1c705e51d413ec6014177042b66e592b975de803 Mon Sep 17 00:00:00 2001 From: Eduard Valeyev Date: Mon, 29 Jul 2024 10:50:54 -0400 Subject: [PATCH] provide finalize_io method to clear references to buffers of standard streams this is only needed if initialize_io captures references to buffers of standard streams that are custom and have finite lifetime --- src/umpire/util/io.cpp | 30 ++++++++++++++++++++++++++++-- src/umpire/util/io.hpp | 13 +++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/umpire/util/io.cpp b/src/umpire/util/io.cpp index 54ad969e7..a46e37f0a 100644 --- a/src/umpire/util/io.cpp +++ b/src/umpire/util/io.cpp @@ -52,10 +52,26 @@ std::ostream& error() namespace util { +namespace detail { + +OutputBuffer& s_log_buffer_accessor() +{ + static OutputBuffer buffer; + return buffer; +} + +OutputBuffer& s_error_buffer_accessor() +{ + static OutputBuffer buffer; + return buffer; +} + +} // namespace detail + void initialize_io(const bool enable_log) { - static util::OutputBuffer s_log_buffer; - static util::OutputBuffer s_error_buffer; + OutputBuffer& s_log_buffer = detail::s_log_buffer_accessor(); + OutputBuffer& s_error_buffer = detail::s_error_buffer_accessor(); s_log_buffer.setConsoleStream(nullptr); s_error_buffer.setConsoleStream(&std::cerr); @@ -121,6 +137,16 @@ void initialize_io(const bool enable_log) MPI::logMpiInfo(); } +void finalize_io() +{ + detail::s_log_buffer_accessor().sync(); + detail::s_log_buffer_accessor().setConsoleStream(nullptr); + detail::s_log_buffer_accessor().setFileStream(nullptr); + detail::s_error_buffer_accessor().sync(); + detail::s_error_buffer_accessor().setConsoleStream(nullptr); + detail::s_error_buffer_accessor().setFileStream(nullptr); +} + void flush_files() { log().flush(); diff --git a/src/umpire/util/io.hpp b/src/umpire/util/io.hpp index cb59e2d9d..9a5050449 100644 --- a/src/umpire/util/io.hpp +++ b/src/umpire/util/io.hpp @@ -29,11 +29,20 @@ const std::string& get_io_output_dir(); const std::string& get_io_output_basename(); /*! - * \brief Initialize the streams. This method is called when ResourceManger is - * initialized. Do not call this manually. + * \brief Initialize the streams. This method is called when ResourceManager is + * initialized. Most users will not need to call this manually. + * \warning This function will capture references to buffers of std::cerr and/or std::cout. If these are using custom + * buffers with explicitly-manager lifetime should may need to call this and finalize_io() to control + * explicitly initialization/finalization of Umpire I/O. */ void initialize_io(const bool enable_log); +/*! + * \brief Counterpart of initialize_io that finalizes the streams and ensures that no live references to the buffers + * of standard streams exist. Most users will not need to call this manually. + */ +void finalize_io(const bool enable_log); + /*! * \brief Synchronize all stream buffers to their respective output sequences. * This function is usually called by exception generating code like