Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions score/launch_manager/src/daemon/src/control/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -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",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,32 @@
#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
namespace score::lcm::internal
{

namespace lcm
bool ControlClientChannel::loadControlNudge()
{
if (nudgeControlClientHandler_ != nullptr)
{
LM_LOG_ERROR() << "Semaphore was already mapped!";
return false;
}

namespace internal
{
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<osal::Semaphore*>(nudgeBuf);
return true;
}

void ControlClientChannel::initialize()
{
Expand Down Expand Up @@ -81,6 +98,8 @@ bool ControlClientChannel::getResponse(ControlClientMessage& msg)
LM_LOG_DEBUG() << "Response retrieved.";
}

nudgeControlClientHandler();

return result;
}

Expand All @@ -89,25 +108,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<osal::Semaphore*>(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(
Expand Down Expand Up @@ -197,6 +198,9 @@ ControlClientChannelP ControlClientChannel::initializeControlClientChannel(int f
lock.unlock();
init_cv_.notify_all();
}

loadControlNudge();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we check for errors here?


return result;
}

Expand Down Expand Up @@ -240,21 +244,24 @@ 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<void>(signal_safe_log("ControlClientChannel semaphore post failed"));
exit(EXIT_FAILURE);
}
}
}

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<void>(signal_safe_log("ControlClientChannel semaphore post failed"));
exit(EXIT_FAILURE);
}
}

void ControlClientChannel::releaseParentMapping()
Expand All @@ -280,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
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -164,60 +165,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<uint32_t>(score::lcm::internal::ProcessLimits::maxLocalBuffSize)];
constexpr static std::string_view shm_name{"/_nudge~._.~me_"};

static_cast<void>(snprintf(
shm_name,
static_cast<uint32_t>(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<off_t>(sizeof(osal::Semaphore))))
{
shm_unlink(shm_name);
::close(fd);
return false;
}

if (0 == ftruncate(fd, static_cast<off_t>(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<osal::Semaphore*>(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<osal::Semaphore*>(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()
Expand Down Expand Up @@ -512,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<int>(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<int>(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)
Expand Down
Loading