Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/catch2/internal/catch_reusable_string_stream.cpp
diff options
context:
space:
mode:
authorMartin Hořeňovský2025-08-23 00:15:53 +0200
committerMartin Hořeňovský2025-08-23 11:08:18 +0200
commit582200a1f8ddd6f435d1264668c7074121c2636c (patch)
tree06629812ca77ebbd77a35424162e197bb979d85e /src/catch2/internal/catch_reusable_string_stream.cpp
parentf4e05a67bb5a57ee6e051fc8c391b32cbf927f7d (diff)
downloadcatch3-582200a1f8ddd6f435d1264668c7074121c2636c.tar.gz
Make message macros (FAIL, WARN, INFO, etc) thread safe
This builds on the existing work to make assertion thread safe, by adding an extra synchronization point in the holder of `ReusableStringStream`'s stream instances, as those are used to build the messages, and finishing the move of message scope holders to be thread-local.
Diffstat (limited to 'src/catch2/internal/catch_reusable_string_stream.cpp')
-rw-r--r--src/catch2/internal/catch_reusable_string_stream.cpp15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/catch2/internal/catch_reusable_string_stream.cpp b/src/catch2/internal/catch_reusable_string_stream.cpp
index 33eafde4..a2dd5a63 100644
--- a/src/catch2/internal/catch_reusable_string_stream.cpp
+++ b/src/catch2/internal/catch_reusable_string_stream.cpp
@@ -7,6 +7,7 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_reusable_string_stream.hpp>
#include <catch2/internal/catch_singletons.hpp>
+#include <catch2/internal/catch_thread_support.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <cstdio>
@@ -20,8 +21,10 @@ namespace Catch {
std::vector<Detail::unique_ptr<std::ostringstream>> m_streams;
std::vector<std::size_t> m_unused;
std::ostringstream m_referenceStream; // Used for copy state/ flags from
+ Detail::Mutex m_mutex;
auto add() -> std::size_t {
+ Detail::LockGuard _( m_mutex );
if( m_unused.empty() ) {
m_streams.push_back( Detail::make_unique<std::ostringstream>() );
return m_streams.size()-1;
@@ -33,9 +36,13 @@ namespace Catch {
}
}
- void release( std::size_t index ) {
- m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
- m_unused.push_back(index);
+ void release( std::size_t index, std::ostream* originalPtr ) {
+ assert( originalPtr );
+ originalPtr->copyfmt( m_referenceStream ); // Restore initial flags and other state
+
+ Detail::LockGuard _( m_mutex );
+ assert( originalPtr == m_streams[index].get() && "Mismatch between release index and stream ptr" );
+ m_unused.push_back( index );
}
};
@@ -47,7 +54,7 @@ namespace Catch {
ReusableStringStream::~ReusableStringStream() {
static_cast<std::ostringstream*>( m_oss )->str("");
m_oss->clear();
- Singleton<StringStreams>::getMutable().release( m_index );
+ Singleton<StringStreams>::getMutable().release( m_index, m_oss );
}
std::string ReusableStringStream::str() const {