From f7458a0c346abedc231874ceb06dc2e810c449d9 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Mon, 23 Feb 2026 21:54:32 -0700 Subject: [PATCH 1/2] Free umpire's reference to our thread sync's error buffer --- src/base/libmesh.C | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/base/libmesh.C b/src/base/libmesh.C index ba36061b43..d23fde4a20 100644 --- a/src/base/libmesh.C +++ b/src/base/libmesh.C @@ -91,6 +91,10 @@ namespace nglib { #include "libmesh/restore_warnings.h" #endif +#ifdef PETSC_HAVE_UMPIRE +#include "umpire/util/io.hpp" +#endif + #include // -------------------------------------------------------- @@ -219,6 +223,10 @@ void uninstall_thread_buffered_sync() { libMesh::err << std::flush; libMesh::err.rdbuf(_err_prewrap_buf); +#ifdef PETSC_HAVE_UMPIRE + // We must release umpire's reference to our error buffer + umpire::util::finalize_io(); +#endif _err_syncd_thread_buffer.reset(); _err_prewrap_buf = nullptr; } From eaf03ef2980eb4a848cb49411b40662b51f83097 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Tue, 24 Feb 2026 08:47:11 -0700 Subject: [PATCH 2/2] Expand comment --- src/base/libmesh.C | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/base/libmesh.C b/src/base/libmesh.C index d23fde4a20..79505df7e7 100644 --- a/src/base/libmesh.C +++ b/src/base/libmesh.C @@ -224,7 +224,12 @@ void uninstall_thread_buffered_sync() libMesh::err << std::flush; libMesh::err.rdbuf(_err_prewrap_buf); #ifdef PETSC_HAVE_UMPIRE - // We must release umpire's reference to our error buffer + // Our libMesh::out and libMesh::err stream proxies are very thin wrappers around, + // by default, std::cout and std::cerr. So when other libraries or users access the + // rdbuf of those streams, then they directly access our thread sync'd custom stream + // buffer. Umpire doesn't use the rdbuf of std::cout, but they *do* use the rdbuf of + // std::cerr, which means they're using our thread sync'd stream buffer. Consequently, + // we must release umpire's reference to our buffer before we destroy it umpire::util::finalize_io(); #endif _err_syncd_thread_buffer.reset();