Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,10 @@ bool Graph::startTransition(ProcessGroupStateID pg_state)

if (nullptr != process_index_list)
{
setState(GraphState::kInTransition);
{
std::shared_lock lock(transition_completion_mutex_);
setState(GraphState::kInTransition);
}

if (GraphState::kInTransition == getState())
{
Expand Down Expand Up @@ -315,7 +318,10 @@ bool Graph::startTransitionToOffState()
requested_state_.pg_state_name_ = off_state_;
}
bool result = false;
setState(GraphState::kInTransition);
{
std::shared_lock lock(transition_completion_mutex_);
setState(GraphState::kInTransition);
}
if (GraphState::kInTransition == getState())
{
std::vector<uint32_t> empty_list{};
Expand All @@ -327,6 +333,8 @@ bool Graph::startTransitionToOffState()

void Graph::nodeExecuted()
{
std::unique_lock lock(transition_completion_mutex_);

GraphState current_state = getState();

if (current_state == GraphState::kInTransition)
Expand Down Expand Up @@ -390,7 +398,6 @@ inline void Graph::handleNonTransitionExecution(GraphState current_state)
<< (static_cast<double>(clock()) / (static_cast<double>(CLOCKS_PER_SEC) / 1000.0)) << "ms";
}
setState(GraphState::kUndefinedState);

if (current_state == GraphState::kAborting)
{
setPendingEvent(abort_code_);
Expand All @@ -414,6 +421,7 @@ void Graph::abort(uint32_t code, ControlClientCode reason)

void Graph::cancel()
{
std::shared_lock lock(transition_completion_mutex_);
setState(GraphState::kCancelled);

if (getState() == GraphState::kCancelled)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <memory>
#include <atomic>
#include <mutex>
#include <shared_mutex>
#include <string_view>
#include <vector>

Expand Down Expand Up @@ -415,6 +416,10 @@ class Graph final {
/// @brief Mutex protecting concurrent access to requested_state_.pg_state_name_
mutable std::mutex requested_state_mutex_{};

/// @brief Mutex protecting new transitions from interfering with concluding transitions.
/// This enforces that, when a transition has completed successfully, it cannot then be cancelled.
std::shared_mutex transition_completion_mutex_;

/// @brief Pointer to the ProcessGroupManager.
ProcessGroupManager* pgm_;

Expand Down
3 changes: 0 additions & 3 deletions tests/integration/complex_monitoring/control_client_mock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ TEST(ComplexMonitoring, ControlClientMock)
auto result = score::mw::lifecycle::LifecycleClient{}.ReportExecutionState(score::mw::lifecycle::ExecutionState::kRunning);
ASSERT_TRUE(result.has_value()) << "ReportExecutionState() failed: " << result.error().Message();
}
// We have to wait for the initial state transition to fully complete, otherwise unexpected failures can occur
// Tracked in https://github.com/eclipse-score/lifecycle/issues/198
sleep(1);

TEST_STEP("Launch monitored process")
{
Expand Down
4 changes: 0 additions & 4 deletions tests/integration/crash_on_startup/control_client_mock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ TEST(CrashOnStartup, ControlClientMock)
ASSERT_TRUE(result.has_value()) << "ReportExecutionState() failed: " << result.error().Message();
}

// We have to wait for the initial state transition to fully complete, otherwise unexpected failures can occur
// Tracked in https://github.com/eclipse-score/lifecycle/issues/198
sleep(1);

// Given a process that crashes on startup twice
TEST_STEP("Launch process crashing on startup twice")
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ TEST(ProcessCrashMonitoring, ControlClientMock)
auto result = score::mw::lifecycle::LifecycleClient{}.ReportExecutionState(score::mw::lifecycle::ExecutionState::kRunning);
ASSERT_TRUE(result.has_value()) << "ReportExecutionState() failed: " << result.error().Message();
}

// We have to wait for the initial state transition to fully complete, otherwise unexpected failures can occur
// Tracked in https://github.com/eclipse-score/lifecycle/issues/198
sleep(1);

TEST_STEP("Start crashing process")
{
Expand Down
4 changes: 0 additions & 4 deletions tests/integration/smoke/control_daemon_mock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ TEST(Smoke, Daemon)
ASSERT_TRUE(result.has_value()) << "client.ReportExecutionState() failed: " << result.error().Message();
}

// We have to wait for the initial state transition to fully complete, otherwise unexpected failures can occur
// Tracked in https://github.com/eclipse-score/lifecycle/issues/198
sleep(1);

TEST_STEP("Activate RunTarget Running")
{
score::cpp::stop_token stop_token;
Expand Down
Loading