mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-11-03 21:49:32 +01:00 
			
		
		
		
	Better handle the global lock to avoid static init issues
This commit is contained in:
		@@ -25,23 +25,23 @@ namespace Catch {
 | 
			
		||||
    :   m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
 | 
			
		||||
        m_resultCapture( getResultCapture() )
 | 
			
		||||
    {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        m_resultCapture.notifyAssertionStarted( m_assertionInfo );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    AssertionHandler::~AssertionHandler() {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        if ( !m_completed ) {
 | 
			
		||||
            m_resultCapture.handleIncomplete( m_assertionInfo );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
 | 
			
		||||
    }
 | 
			
		||||
    void AssertionHandler::handleMessage(ResultWas::OfType resultType, std::string&& message) {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        m_resultCapture.handleMessage( m_assertionInfo, resultType, CATCH_MOVE(message), m_reaction );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -68,26 +68,26 @@ namespace Catch {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void AssertionHandler::handleUnexpectedInflightException() {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void AssertionHandler::handleExceptionThrownAsExpected() {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
 | 
			
		||||
    }
 | 
			
		||||
    void AssertionHandler::handleExceptionNotThrownAsExpected() {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void AssertionHandler::handleUnexpectedExceptionNotThrown() {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void AssertionHandler::handleThrowingCallSkipped() {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,10 @@ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
 | 
			
		||||
    std::recursive_mutex global_lock;
 | 
			
		||||
    std::recursive_mutex& get_global_lock() {
 | 
			
		||||
        static std::recursive_mutex global_lock;
 | 
			
		||||
        return global_lock;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
} // namespace Catch
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,10 +13,10 @@
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
 | 
			
		||||
    extern std::recursive_mutex global_lock;
 | 
			
		||||
    std::recursive_mutex& get_global_lock();
 | 
			
		||||
 | 
			
		||||
    inline auto get_global_lock() {
 | 
			
		||||
        return std::unique_lock<std::recursive_mutex>(global_lock);
 | 
			
		||||
    inline auto take_global_lock() {
 | 
			
		||||
        return std::unique_lock<std::recursive_mutex>(get_global_lock());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
} // namespace Catch
 | 
			
		||||
 
 | 
			
		||||
@@ -45,13 +45,13 @@ namespace Catch {
 | 
			
		||||
    // instead of poking around StringStreams and Singleton.
 | 
			
		||||
 | 
			
		||||
    ReusableStringStream::ReusableStringStream() {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        m_index = Singleton<StringStreams>::getMutable().add();
 | 
			
		||||
        m_oss = Singleton<StringStreams>::getMutable().m_streams[m_index].get();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ReusableStringStream::~ReusableStringStream() {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        static_cast<std::ostringstream*>( m_oss )->str("");
 | 
			
		||||
        m_oss->clear();
 | 
			
		||||
        Singleton<StringStreams>::getMutable().release( m_index );
 | 
			
		||||
 
 | 
			
		||||
@@ -422,22 +422,22 @@ namespace Catch {
 | 
			
		||||
    // Catch benchmark macros call these functions. Since catch internals are not thread-safe locking is needed.
 | 
			
		||||
 | 
			
		||||
    void RunContext::benchmarkPreparing( StringRef name ) {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        auto _ = scopedDeactivate( *m_outputRedirect );
 | 
			
		||||
        m_reporter->benchmarkPreparing( name );
 | 
			
		||||
    }
 | 
			
		||||
    void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        auto _ = scopedDeactivate( *m_outputRedirect );
 | 
			
		||||
        m_reporter->benchmarkStarting( info );
 | 
			
		||||
    }
 | 
			
		||||
    void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        auto _ = scopedDeactivate( *m_outputRedirect );
 | 
			
		||||
        m_reporter->benchmarkEnded( stats );
 | 
			
		||||
    }
 | 
			
		||||
    void RunContext::benchmarkFailed( StringRef error ) {
 | 
			
		||||
        auto lock = get_global_lock();
 | 
			
		||||
        auto lock = take_global_lock();
 | 
			
		||||
        auto _ = scopedDeactivate( *m_outputRedirect );
 | 
			
		||||
        m_reporter->benchmarkFailed( error );
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -466,7 +466,7 @@ void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
 | 
			
		||||
// Catch benchmark macros call these functions. Since catch internals are not thread-safe locking is needed.
 | 
			
		||||
 | 
			
		||||
void ConsoleReporter::benchmarkPreparing( StringRef name ) {
 | 
			
		||||
    auto lock = get_global_lock();
 | 
			
		||||
    auto lock = take_global_lock();
 | 
			
		||||
	lazyPrintWithoutClosingBenchmarkTable();
 | 
			
		||||
 | 
			
		||||
	auto nameCol = TextFlow::Column( static_cast<std::string>( name ) )
 | 
			
		||||
@@ -484,7 +484,7 @@ void ConsoleReporter::benchmarkPreparing( StringRef name ) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
 | 
			
		||||
    auto lock = get_global_lock();
 | 
			
		||||
    auto lock = take_global_lock();
 | 
			
		||||
    (*m_tablePrinter) << info.samples << ColumnBreak()
 | 
			
		||||
        << info.iterations << ColumnBreak();
 | 
			
		||||
    if ( !m_config->benchmarkNoAnalysis() ) {
 | 
			
		||||
@@ -494,7 +494,7 @@ void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
 | 
			
		||||
    ( *m_tablePrinter ) << OutputFlush{};
 | 
			
		||||
}
 | 
			
		||||
void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
 | 
			
		||||
    auto lock = get_global_lock();
 | 
			
		||||
    auto lock = take_global_lock();
 | 
			
		||||
    if (m_config->benchmarkNoAnalysis())
 | 
			
		||||
    {
 | 
			
		||||
        (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
 | 
			
		||||
@@ -512,7 +512,7 @@ void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ConsoleReporter::benchmarkFailed( StringRef error ) {
 | 
			
		||||
    auto lock = get_global_lock();
 | 
			
		||||
    auto lock = take_global_lock();
 | 
			
		||||
    auto guard = m_colour->guardColour( Colour::Red ).engage( m_stream );
 | 
			
		||||
    (*m_tablePrinter)
 | 
			
		||||
        << "Benchmark failed (" << error << ')'
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user