From c4134e6a65718ba7a74368c4407402f58f517d76 Mon Sep 17 00:00:00 2001 From: Maciej Kaszynski Date: Thu, 6 Aug 2026 13:46:41 +0100 Subject: [PATCH 1/3] Fixing log message spam --- .../src/daemon/src/control/BUILD | 1 + .../src/control/control_client_channel.cpp | 62 +++++++++------ .../src/control/control_client_channel.hpp | 3 + .../details/process_group_manager.cpp | 76 +++++++++---------- 4 files changed, 77 insertions(+), 65 deletions(-) diff --git a/score/launch_manager/src/daemon/src/control/BUILD b/score/launch_manager/src/daemon/src/control/BUILD index 090ccec7d..2d1bc3e9d 100644 --- a/score/launch_manager/src/daemon/src/control/BUILD +++ b/score/launch_manager/src/daemon/src/control/BUILD @@ -27,6 +27,7 @@ cc_library( "//score/launch_manager/src/daemon/src/common:constants", "//score/launch_manager/src/daemon/src/common:log", "//score/launch_manager/src/daemon/src/common:process_group_state_id", + "//score/launch_manager/src/daemon/src/common:signal_safe_log", "//score/launch_manager/src/daemon/src/osal:ipc_comms", "@score_baselibs//score/language/futurecpp", ], diff --git a/score/launch_manager/src/daemon/src/control/control_client_channel.cpp b/score/launch_manager/src/daemon/src/control/control_client_channel.cpp index 6f6fba6fc..a5a4acdc2 100644 --- a/score/launch_manager/src/daemon/src/control/control_client_channel.cpp +++ b/score/launch_manager/src/daemon/src/control/control_client_channel.cpp @@ -20,6 +20,7 @@ #include "control_client_channel.hpp" #include "score/mw/launch_manager/common/constants.hpp" #include "score/mw/launch_manager/common/log.hpp" +#include "score/mw/launch_manager/common/signal_safe_log.hpp" namespace score { @@ -30,6 +31,28 @@ namespace lcm namespace internal { +bool ControlClientChannel::loadControlNudge() +{ + if (nudgeControlClientHandler_ != nullptr) + { + LM_LOG_ERROR() << "Semaphore was already mapped!"; + return false; + } + + void* nudgeBuf = mmap( + NULL, sizeof(osal::Semaphore), PROT_WRITE, MAP_SHARED, osal::IpcCommsSync::control_client_handler_nudge_fd, 0); + + if (nudgeBuf == MAP_FAILED) + { + LM_LOG_ERROR() << "mmap of nudge semaphore failed in initializeControlClientChannel:" + << std::string_view{std::strerror(errno)}; + return false; + } + + nudgeControlClientHandler_ = static_cast(nudgeBuf); + return true; +} + void ControlClientChannel::initialize() { request_.empty_.store(true); @@ -81,6 +104,8 @@ bool ControlClientChannel::getResponse(ControlClientMessage& msg) LM_LOG_DEBUG() << "Response retrieved."; } + nudgeControlClientHandler(); + return result; } @@ -89,25 +114,7 @@ void ControlClientChannel::sendRequest(ControlClientMessage& msg) request_.msg_ = msg; request_.empty_ = false; - // now map the semaphore and post on it - // Attempt to map the semaphore - auto* nudgeLM = mmap( - NULL, sizeof(osal::Semaphore), PROT_WRITE, MAP_SHARED, osal::IpcCommsSync::control_client_handler_nudge_fd, 0); - - // RULECHECKER_comment(1, 1, check_c_style_cast, "This is the definition provided by the OS and does a C-style - // cast.", true) - if (nudgeLM != MAP_FAILED) - { - LM_LOG_DEBUG() << "Request sent. Waiting for acknowledgment..."; - auto* semaphore = static_cast(nudgeLM); - - // coverity[cert_mem52_cpp_violation:FALSE] The allocated memory is checked by the containing if statement. - const auto result = semaphore->post(); - SCORE_LANGUAGE_FUTURECPP_ASSERT_MESSAGE( - result == osal::OsalReturnType::kSuccess, "ControlClientChannel semaphore post failed"); - - munmap(nudgeLM, sizeof(osal::Semaphore)); // Unmap the semaphore - } + nudgeControlClientHandler(); const auto result = nudge_LM_Handler_.wait(); SCORE_LANGUAGE_FUTURECPP_ASSERT_MESSAGE( @@ -197,6 +204,9 @@ ControlClientChannelP ControlClientChannel::initializeControlClientChannel(int f lock.unlock(); init_cv_.notify_all(); } + + loadControlNudge(); + return result; } @@ -240,14 +250,16 @@ ControlClientChannelP ControlClientChannel::getControlClientChannel(osal::IpcCom void ControlClientChannel::nudgeControlClientHandler() { - if (nudgeControlClientHandler_) + if (nudgeControlClientHandler_ != nullptr) { - const auto result = nudgeControlClientHandler_->post(); - SCORE_LANGUAGE_FUTURECPP_ASSERT_MESSAGE( - result == osal::OsalReturnType::kSuccess, "ControlClientChannel semaphore post failed"); - - LM_LOG_DEBUG() << "Control Client handler nudged"; + if (nudgeControlClientHandler_->post() != osal::OsalReturnType::kSuccess) + { + static_cast(signal_safe_log("ControlClientChannel semaphore post failed")); + exit(EXIT_FAILURE); + } } + + LM_LOG_DEBUG() << "Control Client handler nudged"; } void ControlClientChannel::nudgeLMHandler() diff --git a/score/launch_manager/src/daemon/src/control/control_client_channel.hpp b/score/launch_manager/src/daemon/src/control/control_client_channel.hpp index 86d6cd370..73d928389 100644 --- a/score/launch_manager/src/daemon/src/control/control_client_channel.hpp +++ b/score/launch_manager/src/daemon/src/control/control_client_channel.hpp @@ -171,6 +171,9 @@ class ControlClientChannel final /// @brief Desctructor, deleted. We cannot create or delete objects of this type in the normal ways. ~ControlClientChannel() = delete; + /// @brief loads the control channel's nudge semaphore. + static bool loadControlNudge(); + /// @brief Initialise the comms channels /// called when the shared memory is initially created by Launch Manager void initialize(); diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager.cpp index eb75ade8c..257425d3b 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager.cpp @@ -164,60 +164,56 @@ void ProcessGroupManager::deinitialize() inline bool ProcessGroupManager::initializeControlClientHandler() { - bool result = false; - // Create shared memory for the nudge semaphore, using the specific // file descriptor osal::Comms::control_client_handler_nudge_fd, and a random name. // The name is removed from the file system after creation, memory // is mapped and a pointer stored, the FD is kept open. ControlClientChannel::nudgeControlClientHandler_ = nullptr; - char shm_name[static_cast(score::lcm::internal::ProcessLimits::maxLocalBuffSize)]; + constexpr static std::string_view shm_name{"/_nudge~._.~me_"}; - static_cast(snprintf( - shm_name, - static_cast(score::lcm::internal::ProcessLimits::maxLocalBuffSize), - "/_nudge~._.~me_")); // random name - int fd = shm_open(shm_name, O_CREAT | O_EXCL | O_RDWR, 0U); + int fd = shm_open(shm_name.begin(), O_CREAT | O_EXCL | O_RDWR, 0U); + if (fd <= 0) + { + return false; + } + shm_unlink(shm_name.begin()); - if (fd >= 0) + if (0 != ftruncate(fd, static_cast(sizeof(osal::Semaphore)))) { - shm_unlink(shm_name); + ::close(fd); + return false; + } - if (0 == ftruncate(fd, static_cast(sizeof(osal::Semaphore)))) - { - int fd2 = - dup2(fd, osal::IpcCommsSync::control_client_handler_nudge_fd); // always make sure we are using fd=4 - close(fd); + int fd2 = dup2(fd, osal::IpcCommsSync::control_client_handler_nudge_fd); // always make sure we are using fd=4 + ::close(fd); - // dup2 clears the O_CLOEXEC flag so this needs to be set again - if (fcntl(fd2, F_SETFD, FD_CLOEXEC) != 0) - { - ::close(fd2); - return false; - } + // dup2 clears the O_CLOEXEC flag so this needs to be set again + if (fcntl(fd2, F_SETFD, FD_CLOEXEC) != 0) + { + ::close(fd2); + return false; + } - if (osal::IpcCommsSync::control_client_handler_nudge_fd == fd2) - { - void* buf = mmap(NULL, sizeof(osal::Semaphore), PROT_WRITE, MAP_SHARED, fd2, 0); + if (osal::IpcCommsSync::control_client_handler_nudge_fd != fd2) + { + ::close(fd2); + return false; + } - // RULECHECKER_comment(1, 1, check_c_style_cast, "This is the definition provided by the OS and does a - // C-style cast.", true) - if (MAP_FAILED != buf) - { - ControlClientChannel::nudgeControlClientHandler_ = static_cast(buf); - // coverity[cert_mem52_cpp_violation:FALSE] The allocated memory is checked by the containing if - // statement. - const auto osal_result = ControlClientChannel::nudgeControlClientHandler_->init(0U, true); - SCORE_LANGUAGE_FUTURECPP_ASSERT_MESSAGE( - osal_result == OsalReturnType::kSuccess, "ControlClientChannel semaphore init failed"); - - result = true; - } - } - } + void* buf = mmap(NULL, sizeof(osal::Semaphore), PROT_WRITE, MAP_SHARED, fd2, 0); + + if (MAP_FAILED == buf) + { + ::close(fd2); + return false; } - return result; + ControlClientChannel::nudgeControlClientHandler_ = static_cast(buf); + const auto osal_result = ControlClientChannel::nudgeControlClientHandler_->init(0U, true); + SCORE_LANGUAGE_FUTURECPP_ASSERT_MESSAGE( + osal_result == OsalReturnType::kSuccess, "ControlClientChannel semaphore init failed"); + + return true; } inline bool ProcessGroupManager::initializeProcessGroups() From 3dac2472d32e58afce6ed875721ffd1477886b53 Mon Sep 17 00:00:00 2001 From: Maciej Kaszynski Date: Thu, 6 Aug 2026 14:22:32 +0100 Subject: [PATCH 2/3] Removing a nudge --- .../details/process_group_manager.cpp | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager.cpp b/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager.cpp index 257425d3b..dc0a529c1 100644 --- a/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager.cpp +++ b/score/launch_manager/src/daemon/src/process_group_manager/details/process_group_manager.cpp @@ -31,6 +31,7 @@ static std::atomic_bool em_cancelled{false}; static void my_signal_handler(int) { em_cancelled.store(true); + ControlClientChannel::nudgeControlClientHandler(); } void ProcessGroupManager::cancel() @@ -508,27 +509,23 @@ bool ProcessGroupManager::sendResponse(ControlClientMessage msg) { auto pin = getProcessInfoNode( msg.originating_control_client_.process_group_index_, msg.originating_control_client_.process_index_); - bool ret = true; - if (pin) + if (pin == nullptr) { - auto scc = pin->getControlClientChannel(); + return false; + } + auto scc = pin->getControlClientChannel(); - if (scc) - { - LM_LOG_DEBUG() << "ProcessGroupManager::ControlClientHandler: Sending" - << scc->toString(msg.request_or_response_) << "(" - << static_cast(msg.request_or_response_) << ") re state" - << msg.process_group_state_.pg_state_name_ << "of PG" << msg.process_group_state_.pg_name_; - ret = scc->sendResponse(msg); - if (!ret) - { - ControlClientChannel::nudgeControlClientHandler(); - } - } + if (scc == nullptr) + { + return false; } - return ret; + LM_LOG_DEBUG() << "ProcessGroupManager::ControlClientHandler: Sending" << scc->toString(msg.request_or_response_) + << "(" << static_cast(msg.request_or_response_) << ") re state" + << msg.process_group_state_.pg_state_name_ << "of PG" << msg.process_group_state_.pg_name_; + + return scc->sendResponse(msg); } inline void ProcessGroupManager::controlClientRequests(Graph& pg) From 1089cc01ecf29c38f81afaee4a4707779e543c5e Mon Sep 17 00:00:00 2001 From: Maciej Kaszynski Date: Thu, 6 Aug 2026 17:21:33 +0100 Subject: [PATCH 3/3] Fixing tsan --- .../src/control/control_client_channel.cpp | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/score/launch_manager/src/daemon/src/control/control_client_channel.cpp b/score/launch_manager/src/daemon/src/control/control_client_channel.cpp index a5a4acdc2..a305a1185 100644 --- a/score/launch_manager/src/daemon/src/control/control_client_channel.cpp +++ b/score/launch_manager/src/daemon/src/control/control_client_channel.cpp @@ -22,13 +22,7 @@ #include "score/mw/launch_manager/common/log.hpp" #include "score/mw/launch_manager/common/signal_safe_log.hpp" -namespace score -{ - -namespace lcm -{ - -namespace internal +namespace score::lcm::internal { bool ControlClientChannel::loadControlNudge() @@ -258,15 +252,16 @@ void ControlClientChannel::nudgeControlClientHandler() exit(EXIT_FAILURE); } } - - LM_LOG_DEBUG() << "Control Client handler nudged"; } void ControlClientChannel::nudgeLMHandler() { const auto result = nudge_LM_Handler_.post(); - SCORE_LANGUAGE_FUTURECPP_ASSERT_MESSAGE( - result == osal::OsalReturnType::kSuccess, "ControlClientChannel semaphore post failed"); + if (result != osal::OsalReturnType::kSuccess) + { + static_cast(signal_safe_log("ControlClientChannel semaphore post failed")); + exit(EXIT_FAILURE); + } } void ControlClientChannel::releaseParentMapping() @@ -292,8 +287,4 @@ bool ControlClientChannel::is_initialized_ = false; std::condition_variable ControlClientChannel::init_cv_{}; std::mutex ControlClientChannel::init_mutex_{}; -} // namespace internal - -} // namespace lcm - -} // namespace score +} // namespace score::lcm::internal