From 3acb42fbe1cdc208688cd432dd0ba41c889c0d01 Mon Sep 17 00:00:00 2001 From: Brendan Emery Date: Thu, 26 Mar 2026 08:56:44 +0100 Subject: [PATCH] mw/com: Use MeyerSingleton class to initialize static Runtime Due to what seems like a compiler bug in gcc, the destruction sequence of static objects when compiling with gcc can be unexpected when multiple threads attempted to create the static objects. Full details are in the ticket and class documentation for the MeyerSingleton class. Bug ticket: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99613 This commit adds usage of a MeyerSingleton class which provides a workaround to this bug. --- score/mw/com/impl/BUILD | 1 + score/mw/com/impl/runtime.cpp | 9 ++++----- score/mw/com/impl/runtime.h | 2 -- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/score/mw/com/impl/BUILD b/score/mw/com/impl/BUILD index 963ba315c..45e7f4423 100644 --- a/score/mw/com/impl/BUILD +++ b/score/mw/com/impl/BUILD @@ -877,6 +877,7 @@ cc_library( "@score_baselibs//score/concurrency:long_running_threads_container", "@score_baselibs//score/language/futurecpp", "@score_baselibs//score/memory/shared:types", + "@score_baselibs//score/utils/meyer_singleton", "@score_logging//score/mw/log", ], ) diff --git a/score/mw/com/impl/runtime.cpp b/score/mw/com/impl/runtime.cpp index 25e722337..24454b858 100644 --- a/score/mw/com/impl/runtime.cpp +++ b/score/mw/com/impl/runtime.cpp @@ -148,7 +148,7 @@ Runtime& Runtime::getInstanceInternal() noexcept // Suppress "AUTOSAR C++14 A3-3-2" rule finding. This rule states: "Static and thread-local objects shall be // constant-initialized.". This cannot be constexpr as the lambda function executes at runtime. // coverity[autosar_cpp14_a3_3_2_violation] - static Runtime instance{([]() -> std::pair> { + return singleton::MeyerSingleton::GetInstanceInitializedWithCallable([]() -> Runtime { std::lock_guard lock{mutex_}; runtime_initialization_locked_ = true; if (!initialization_config_.has_value()) @@ -156,7 +156,7 @@ Runtime& Runtime::getInstanceInternal() noexcept runtime::RuntimeConfiguration runtime_configuration{}; auto configuration = configuration::Parse(runtime_configuration.GetConfigurationPath().Native()); auto tracing_config = ParseTraceConfig(configuration); - return std::make_pair(std::move(configuration), std::move(tracing_config)); + return Runtime{std::make_pair(std::move(configuration), std::move(tracing_config))}; } else { @@ -164,10 +164,9 @@ Runtime& Runtime::getInstanceInternal() noexcept auto configuration_pair = std::make_pair(std::move(initialization_config_.value()), std::move(tracing_config)); initialization_config_.reset(); - return configuration_pair; + return Runtime{std::move(configuration_pair)}; } - })()}; - return instance; + }); } Runtime::Runtime(std::pair&&> configs) diff --git a/score/mw/com/impl/runtime.h b/score/mw/com/impl/runtime.h index 24adf4598..00d789c8e 100644 --- a/score/mw/com/impl/runtime.h +++ b/score/mw/com/impl/runtime.h @@ -21,14 +21,12 @@ #include "score/mw/com/impl/instance_specifier.h" #include "score/mw/com/impl/service_discovery.h" #include "score/mw/com/impl/tracing/configuration/tracing_filter_config.h" -#include "score/mw/com/impl/tracing/tracing_runtime.h" #include "score/mw/com/runtime_configuration.h" #include #include #include -#include #include #include #include