diff --git a/fairmq/Device.cxx b/fairmq/Device.cxx index fa267f53..c27ea8b5 100644 --- a/fairmq/Device.cxx +++ b/fairmq/Device.cxx @@ -91,7 +91,6 @@ Device::Device(ProgOptions* config, tools::Version version) , fVersion(version) , fRate(DefaultRate) , fInitializationTimeoutInS(DefaultInitTimeout) - , fTransitioning(false) { SubscribeToNewTransition("device", [&](Transition transition) { LOG(trace) << "device notified on new transition: " << transition; @@ -143,73 +142,6 @@ Device::Device(ProgOptions* config, tools::Version version) } #pragma GCC diagnostic pop -void Device::TransitionTo(State s) -{ - { - lock_guard lock(fTransitionMtx); - if (fTransitioning) { - LOG(debug) << "Attempting a transition with TransitionTo() while another one is already in progress"; - throw OngoingTransition("Attempting a transition with TransitionTo() while another one is already in progress"); - } - fTransitioning = true; - } - - using mq::State; - - StateQueue sq; - StateSubscription ss(tools::ToString(fId, ".TransitionTo"), fStateMachine, sq); - - State currentState = GetCurrentState(); - - while (s != currentState) { - switch (currentState) { - case State::Idle: - if (s == State::Exiting) { ChangeStateOrThrow(Transition::End); } - else { ChangeStateOrThrow(Transition::InitDevice); } - break; - case State::InitializingDevice: - ChangeStateOrThrow(Transition::CompleteInit); - break; - case State::Initialized: - if (s == State::Exiting || s == State::Idle) { ChangeStateOrThrow(Transition::ResetDevice); } - else { ChangeStateOrThrow(Transition::Bind); } - break; - case State::Bound: - if (s == State::DeviceReady || s == State::Ready || s == State::Running) { ChangeStateOrThrow(Transition::Connect); } - else { ChangeStateOrThrow(Transition::ResetDevice); } - break; - case State::DeviceReady: - if (s == State::Running || s == State::Ready) { ChangeStateOrThrow(Transition::InitTask); } - else { ChangeStateOrThrow(Transition::ResetDevice); } - break; - case State::Ready: - if (s == State::Running) { ChangeStateOrThrow(Transition::Run); } - else { ChangeStateOrThrow(Transition::ResetTask); } - break; - case State::Running: - ChangeStateOrThrow(Transition::Stop); - break; - case State::Binding: - case State::Connecting: - case State::InitializingTask: - case State::ResettingDevice: - case State::ResettingTask: - LOG(debug) << "TransitionTo ignoring state: " << currentState << " (expected, automatic transition)."; - break; - default: - LOG(debug) << "TransitionTo ignoring state: " << currentState; - break; - } - - currentState = sq.WaitForNext(); - } - - { - lock_guard lock(fTransitionMtx); - fTransitioning = false; - } -} - void Device::InitWrapper() { // run initialization once CompleteInit transition is requested diff --git a/fairmq/Device.h b/fairmq/Device.h index 8f95b499..0ec5970c 100644 --- a/fairmq/Device.h +++ b/fairmq/Device.h @@ -552,8 +552,6 @@ class Device /// @param state state to wait for void WaitForState(const std::string& state) { WaitForState(GetState(state)); } - void TransitionTo(State state); - /// @brief Subscribe with a callback to state changes /// @param key id to identify your subscription /// @param callback callback (called with the new state as the parameter) @@ -683,8 +681,6 @@ class Device StateQueue fStateQueue; std::mutex fTransportMtx; ///< guards access to transports container - std::mutex fTransitionMtx; - bool fTransitioning; }; } // namespace fair::mq diff --git a/test/device/_transitions.cxx b/test/device/_transitions.cxx index e1eea343..dcf320ed 100644 --- a/test/device/_transitions.cxx +++ b/test/device/_transitions.cxx @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * + * Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * * This software is distributed under the terms of the * * GNU Lesser General Public Licence (LGPL) version 3, * @@ -20,83 +20,6 @@ namespace using namespace std; using namespace fair::mq; -class SlowDevice : public Device -{ - public: - SlowDevice() = default; - - protected: - void Init() override - { - this_thread::sleep_for(chrono::milliseconds(100)); - } -}; - -void transitionTo(const vector& states, int numExpectedStates) -{ - Device device; - - thread t([&] { - for (const auto& s : states) { - device.TransitionTo(s); - } - }); - - int numStates = 0; - - device.SubscribeToStateChange("testRunner", [&numStates](State /* state */) { - numStates++; - }); - - device.RunStateMachine(); - - if (t.joinable()) { - t.join(); - } - - LOG(info) << "expected " << numExpectedStates << ", encountered " << numStates << " states"; - EXPECT_EQ(numStates, numExpectedStates); -} - -TEST(Transitions, TransitionTo) -{ - transitionTo({State::Exiting}, 2); - transitionTo({State::InitializingDevice, State::Initialized, State::Exiting}, 6); - transitionTo({State::Initialized, State::Exiting}, 6); - transitionTo({State::DeviceReady, State::Bound, State::Running, State::Exiting}, 24); - transitionTo({State::Ready, State::Exiting}, 14); - transitionTo({State::Running, State::Exiting}, 16); -} - -TEST(Transitions, ConcurrentTransitionTos) -{ - fair::Logger::SetConsoleSeverity("debug"); - SlowDevice slowDevice; - - vector states({State::Ready, State::Exiting}); - - thread t1([&] { - for (const auto& s : states) { - slowDevice.TransitionTo(s); - } - }); - - thread t2([&] { - this_thread::sleep_for(chrono::milliseconds(50)); - ASSERT_THROW(slowDevice.TransitionTo(State::Exiting), OngoingTransition); - }); - - slowDevice.RunStateMachine(); - - if (t1.joinable()) { - t1.join(); - } - - if (t2.joinable()) { - t2.join(); - } -} - TEST(Transitions, InvalidChangeState) { Device device;