From 3566c7ee5ccfab33434ce239fe15b3fef549ebf7 Mon Sep 17 00:00:00 2001 From: shockp Date: Sun, 5 Apr 2026 12:26:10 +0200 Subject: [PATCH] GH-49433: [C++] Buffer ARROW_LOG output to prevent thread interleaving When using the ARROW_LOG macros from multiple threads, messages were getting mingled together in stderr because the operator<< was writing directly to the global stream piece-by-piece. This commit introduces an internal std::ostringstream buffer to CerrLog so that messages are accumulated locally and flushed atomically upon destruction. --- cpp/src/arrow/util/logging.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cpp/src/arrow/util/logging.cc b/cpp/src/arrow/util/logging.cc index 993c5306ca4a..15e3369dcdeb 100644 --- a/cpp/src/arrow/util/logging.cc +++ b/cpp/src/arrow/util/logging.cc @@ -24,6 +24,7 @@ #endif #include #include +#include #ifdef ARROW_USE_GLOG @@ -67,7 +68,7 @@ class CerrLog { virtual ~CerrLog() { if (has_logged_) { - std::cerr << std::endl; + std::cerr << buffer_.str() << std::endl; } if (severity_ == ArrowLogLevel::ARROW_FATAL) { PrintBackTrace(); @@ -77,14 +78,14 @@ class CerrLog { std::ostream& Stream() { has_logged_ = true; - return std::cerr; + return buffer_; } template CerrLog& operator<<(const T& t) { if (severity_ != ArrowLogLevel::ARROW_DEBUG) { has_logged_ = true; - std::cerr << t; + buffer_ << t; } return *this; } @@ -92,6 +93,7 @@ class CerrLog { protected: const ArrowLogLevel severity_; bool has_logged_; + std::ostringstream buffer_; void PrintBackTrace() { #ifdef ARROW_WITH_BACKTRACE