mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-13 08:41:16 +00:00
Run state handlers on the main thread (breaking change for control).
This commit is contained in:
parent
c064da91df
commit
a53ef79552
|
@ -13,11 +13,12 @@
|
||||||
using namespace fair::mq;
|
using namespace fair::mq;
|
||||||
|
|
||||||
DeviceRunner::DeviceRunner(int argc, char* const argv[])
|
DeviceRunner::DeviceRunner(int argc, char* const argv[])
|
||||||
: fRawCmdLineArgs{tools::ToStrVector(argc, argv, false)}
|
: fRawCmdLineArgs(tools::ToStrVector(argc, argv, false))
|
||||||
, fPluginManager{PluginManager::MakeFromCommandLineOptions(fRawCmdLineArgs)}
|
, fPluginManager(PluginManager::MakeFromCommandLineOptions(fRawCmdLineArgs))
|
||||||
, fDevice{nullptr}
|
, fConfig()
|
||||||
{
|
, fDevice(nullptr)
|
||||||
}
|
, fEvents()
|
||||||
|
{}
|
||||||
|
|
||||||
auto DeviceRunner::Run() -> int
|
auto DeviceRunner::Run() -> int
|
||||||
{
|
{
|
||||||
|
@ -87,6 +88,9 @@ auto DeviceRunner::Run() -> int
|
||||||
// Instantiate and run plugins
|
// Instantiate and run plugins
|
||||||
fPluginManager->InstantiatePlugins();
|
fPluginManager->InstantiatePlugins();
|
||||||
|
|
||||||
|
// Run the device
|
||||||
|
fDevice->RunStateMachine();
|
||||||
|
|
||||||
// Wait for control plugin to release device control
|
// Wait for control plugin to release device control
|
||||||
fPluginManager->WaitForPluginsToReleaseDeviceControl();
|
fPluginManager->WaitForPluginsToReleaseDeviceControl();
|
||||||
|
|
||||||
|
|
|
@ -416,6 +416,8 @@ class FairMQDevice : public FairMQStateMachine
|
||||||
void SetRawCmdLineArgs(const std::vector<std::string>& args) { fRawCmdLineArgs = args; }
|
void SetRawCmdLineArgs(const std::vector<std::string>& args) { fRawCmdLineArgs = args; }
|
||||||
std::vector<std::string> GetRawCmdLineArgs() const { return fRawCmdLineArgs; }
|
std::vector<std::string> GetRawCmdLineArgs() const { return fRawCmdLineArgs; }
|
||||||
|
|
||||||
|
void RunStateMachine() { ProcessWork(); };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<FairMQTransportFactory> fTransportFactory; ///< Default transport factory
|
std::shared_ptr<FairMQTransportFactory> fTransportFactory; ///< Default transport factory
|
||||||
std::unordered_map<fair::mq::Transport, std::shared_ptr<FairMQTransportFactory>> fTransports; ///< Container for transports
|
std::unordered_map<fair::mq::Transport, std::shared_ptr<FairMQTransportFactory>> fTransports; ///< Container for transports
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FairMQStateMachine.h"
|
#include "FairMQStateMachine.h"
|
||||||
|
#include <fairmq/Tools.h>
|
||||||
|
|
||||||
// Increase maximum number of boost::msm states (default is 10)
|
// Increase maximum number of boost::msm states (default is 10)
|
||||||
// This #define has to be before any msm header includes
|
// This #define has to be before any msm header includes
|
||||||
|
@ -29,13 +30,20 @@
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <thread>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <array>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace boost::msm::front;
|
||||||
|
|
||||||
namespace msmf = boost::msm::front;
|
namespace std
|
||||||
|
{
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct hash<FairMQStateMachine::Event> : fair::mq::tools::HashEnum<FairMQStateMachine::Event> {};
|
||||||
|
|
||||||
|
} /* namespace std */
|
||||||
|
|
||||||
namespace fair
|
namespace fair
|
||||||
{
|
{
|
||||||
|
@ -44,31 +52,105 @@ namespace mq
|
||||||
namespace fsm
|
namespace fsm
|
||||||
{
|
{
|
||||||
|
|
||||||
// defining events for the boost MSM state machine
|
// list of FSM states
|
||||||
struct INIT_DEVICE_E { string name() const { return "INIT_DEVICE"; } };
|
struct OK_FSM_STATE : public state<> { static string Name() { return "OK"; } static FairMQStateMachine::State Type() { return FairMQStateMachine::State::OK; } };
|
||||||
struct internal_DEVICE_READY_E { string name() const { return "internal_DEVICE_READY"; } };
|
struct ERROR_FSM_STATE : public terminate_state<> { static string Name() { return "ERROR"; } static FairMQStateMachine::State Type() { return FairMQStateMachine::State::Error; } };
|
||||||
struct INIT_TASK_E { string name() const { return "INIT_TASK"; } };
|
|
||||||
struct internal_READY_E { string name() const { return "internal_READY"; } };
|
|
||||||
struct RUN_E { string name() const { return "RUN"; } };
|
|
||||||
struct PAUSE_E { string name() const { return "PAUSE"; } };
|
|
||||||
struct STOP_E { string name() const { return "STOP"; } };
|
|
||||||
struct RESET_TASK_E { string name() const { return "RESET_TASK"; } };
|
|
||||||
struct RESET_DEVICE_E { string name() const { return "RESET_DEVICE"; } };
|
|
||||||
struct internal_IDLE_E { string name() const { return "internal_IDLE"; } };
|
|
||||||
struct END_E { string name() const { return "END"; } };
|
|
||||||
struct ERROR_FOUND_E { string name() const { return "ERROR_FOUND"; } };
|
|
||||||
|
|
||||||
// deactivate the warning for non-virtual destructor thrown in the boost library
|
struct IDLE_FSM_STATE : public state<> { static string Name() { return "IDLE"; } static FairMQStateMachine::State Type() { return FairMQStateMachine::State::IDLE; } };
|
||||||
#if defined(__clang__)
|
struct INITIALIZING_DEVICE_FSM_STATE : public state<> { static string Name() { return "INITIALIZING_DEVICE"; } static FairMQStateMachine::State Type() { return FairMQStateMachine::State::INITIALIZING_DEVICE; } };
|
||||||
_Pragma("clang diagnostic push")
|
struct DEVICE_READY_FSM_STATE : public state<> { static string Name() { return "DEVICE_READY"; } static FairMQStateMachine::State Type() { return FairMQStateMachine::State::DEVICE_READY; } };
|
||||||
_Pragma("clang diagnostic ignored \"-Wnon-virtual-dtor\"")
|
struct INITIALIZING_TASK_FSM_STATE : public state<> { static string Name() { return "INITIALIZING_TASK"; } static FairMQStateMachine::State Type() { return FairMQStateMachine::State::INITIALIZING_TASK; } };
|
||||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
struct READY_FSM_STATE : public state<> { static string Name() { return "READY"; } static FairMQStateMachine::State Type() { return FairMQStateMachine::State::READY; } };
|
||||||
_Pragma("GCC diagnostic push")
|
struct RUNNING_FSM_STATE : public state<> { static string Name() { return "RUNNING"; } static FairMQStateMachine::State Type() { return FairMQStateMachine::State::RUNNING; } };
|
||||||
_Pragma("GCC diagnostic ignored \"-Wnon-virtual-dtor\"")
|
struct PAUSED_FSM_STATE : public state<> { static string Name() { return "PAUSED"; } static FairMQStateMachine::State Type() { return FairMQStateMachine::State::PAUSED; } };
|
||||||
#endif
|
struct RESETTING_TASK_FSM_STATE : public state<> { static string Name() { return "RESETTING_TASK"; } static FairMQStateMachine::State Type() { return FairMQStateMachine::State::RESETTING_TASK; } };
|
||||||
|
struct RESETTING_DEVICE_FSM_STATE : public state<> { static string Name() { return "RESETTING_DEVICE"; } static FairMQStateMachine::State Type() { return FairMQStateMachine::State::RESETTING_DEVICE; } };
|
||||||
|
struct EXITING_FSM_STATE : public state<> { static string Name() { return "EXITING"; } static FairMQStateMachine::State Type() { return FairMQStateMachine::State::EXITING; } };
|
||||||
|
|
||||||
|
// list of FSM events
|
||||||
|
struct INIT_DEVICE_FSM_EVENT { static string Name() { return "INIT_DEVICE"; } static FairMQStateMachine::Event Type() { return FairMQStateMachine::Event::INIT_DEVICE; } };
|
||||||
|
struct internal_DEVICE_READY_FSM_EVENT { static string Name() { return "internal_DEVICE_READY"; } static FairMQStateMachine::Event Type() { return FairMQStateMachine::Event::internal_DEVICE_READY; } };
|
||||||
|
struct INIT_TASK_FSM_EVENT { static string Name() { return "INIT_TASK"; } static FairMQStateMachine::Event Type() { return FairMQStateMachine::Event::INIT_TASK; } };
|
||||||
|
struct internal_READY_FSM_EVENT { static string Name() { return "internal_READY"; } static FairMQStateMachine::Event Type() { return FairMQStateMachine::Event::internal_READY; } };
|
||||||
|
struct RUN_FSM_EVENT { static string Name() { return "RUN"; } static FairMQStateMachine::Event Type() { return FairMQStateMachine::Event::RUN; } };
|
||||||
|
struct PAUSE_FSM_EVENT { static string Name() { return "PAUSE"; } static FairMQStateMachine::Event Type() { return FairMQStateMachine::Event::PAUSE; } };
|
||||||
|
struct STOP_FSM_EVENT { static string Name() { return "STOP"; } static FairMQStateMachine::Event Type() { return FairMQStateMachine::Event::STOP; } };
|
||||||
|
struct RESET_TASK_FSM_EVENT { static string Name() { return "RESET_TASK"; } static FairMQStateMachine::Event Type() { return FairMQStateMachine::Event::RESET_TASK; } };
|
||||||
|
struct RESET_DEVICE_FSM_EVENT { static string Name() { return "RESET_DEVICE"; } static FairMQStateMachine::Event Type() { return FairMQStateMachine::Event::RESET_DEVICE; } };
|
||||||
|
struct internal_IDLE_FSM_EVENT { static string Name() { return "internal_IDLE"; } static FairMQStateMachine::Event Type() { return FairMQStateMachine::Event::internal_IDLE; } };
|
||||||
|
struct END_FSM_EVENT { static string Name() { return "END"; } static FairMQStateMachine::Event Type() { return FairMQStateMachine::Event::END; } };
|
||||||
|
struct ERROR_FOUND_FSM_EVENT { static string Name() { return "ERROR_FOUND"; } static FairMQStateMachine::Event Type() { return FairMQStateMachine::Event::ERROR_FOUND; } };
|
||||||
|
|
||||||
|
static array<string, 12> stateNames =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"OK",
|
||||||
|
"Error",
|
||||||
|
"IDLE",
|
||||||
|
"INITIALIZING_DEVICE",
|
||||||
|
"DEVICE_READY",
|
||||||
|
"INITIALIZING_TASK",
|
||||||
|
"READY",
|
||||||
|
"RUNNING",
|
||||||
|
"PAUSED",
|
||||||
|
"RESETTING_TASK",
|
||||||
|
"RESETTING_DEVICE",
|
||||||
|
"EXITING"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static array<string, 12> eventNames =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"INIT_DEVICE",
|
||||||
|
"internal_DEVICE_READY",
|
||||||
|
"INIT_TASK",
|
||||||
|
"internal_READY",
|
||||||
|
"RUN",
|
||||||
|
"PAUSE",
|
||||||
|
"STOP",
|
||||||
|
"RESET_TASK",
|
||||||
|
"RESET_DEVICE",
|
||||||
|
"internal_IDLE",
|
||||||
|
"END",
|
||||||
|
"ERROR_FOUND"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static map<string, int> stateNumbers =
|
||||||
|
{
|
||||||
|
{ "OK", FairMQStateMachine::State::OK },
|
||||||
|
{ "Error", FairMQStateMachine::State::Error },
|
||||||
|
{ "IDLE", FairMQStateMachine::State::IDLE },
|
||||||
|
{ "INITIALIZING_DEVICE", FairMQStateMachine::State::INITIALIZING_DEVICE },
|
||||||
|
{ "DEVICE_READY", FairMQStateMachine::State::DEVICE_READY },
|
||||||
|
{ "INITIALIZING_TASK", FairMQStateMachine::State::INITIALIZING_TASK },
|
||||||
|
{ "READY", FairMQStateMachine::State::READY },
|
||||||
|
{ "RUNNING", FairMQStateMachine::State::RUNNING },
|
||||||
|
{ "PAUSED", FairMQStateMachine::State::PAUSED },
|
||||||
|
{ "RESETTING_TASK", FairMQStateMachine::State::RESETTING_TASK },
|
||||||
|
{ "RESETTING_DEVICE", FairMQStateMachine::State::RESETTING_DEVICE },
|
||||||
|
{ "EXITING", FairMQStateMachine::State::EXITING }
|
||||||
|
};
|
||||||
|
|
||||||
|
static map<string, int> eventNumbers =
|
||||||
|
{
|
||||||
|
{ "INIT_DEVICE", FairMQStateMachine::Event::INIT_DEVICE },
|
||||||
|
{ "internal_DEVICE_READY", FairMQStateMachine::Event::internal_DEVICE_READY },
|
||||||
|
{ "INIT_TASK", FairMQStateMachine::Event::INIT_TASK },
|
||||||
|
{ "internal_READY", FairMQStateMachine::Event::internal_READY },
|
||||||
|
{ "RUN", FairMQStateMachine::Event::RUN },
|
||||||
|
{ "PAUSE", FairMQStateMachine::Event::PAUSE },
|
||||||
|
{ "STOP", FairMQStateMachine::Event::STOP },
|
||||||
|
{ "RESET_TASK", FairMQStateMachine::Event::RESET_TASK },
|
||||||
|
{ "RESET_DEVICE", FairMQStateMachine::Event::RESET_DEVICE },
|
||||||
|
{ "internal_IDLE", FairMQStateMachine::Event::internal_IDLE },
|
||||||
|
{ "END", FairMQStateMachine::Event::END },
|
||||||
|
{ "ERROR_FOUND", FairMQStateMachine::Event::ERROR_FOUND }
|
||||||
|
};
|
||||||
|
|
||||||
// defining the boost MSM state machine
|
// defining the boost MSM state machine
|
||||||
struct Machine_ : public msmf::state_machine_def<Machine_>
|
struct Machine_ : public state_machine_def<Machine_>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Machine_()
|
Machine_()
|
||||||
|
@ -81,23 +163,22 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
, fWorkAvailable(false)
|
, fWorkAvailable(false)
|
||||||
, fStateChangeSignal()
|
, fStateChangeSignal()
|
||||||
, fStateChangeSignalsMap()
|
, fStateChangeSignalsMap()
|
||||||
, fTerminationRequested(false)
|
|
||||||
, fState()
|
, fState()
|
||||||
, fWorkerThread()
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~Machine_()
|
virtual ~Machine_()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
// initial states
|
||||||
|
using initial_state = boost::mpl::vector<IDLE_FSM_STATE, OK_FSM_STATE>;
|
||||||
|
|
||||||
template<typename Event, typename FSM>
|
template<typename Event, typename FSM>
|
||||||
void on_entry(Event const&, FSM& fsm)
|
void on_entry(Event const&, FSM& fsm)
|
||||||
{
|
{
|
||||||
LOG(state) << "Starting FairMQ state machine";
|
LOG(state) << "Starting FairMQ state machine";
|
||||||
fState = FairMQStateMachine::IDLE;
|
fState = FairMQStateMachine::IDLE;
|
||||||
|
LOG(state) << "Entering IDLE state";
|
||||||
fsm.CallStateChangeCallbacks(FairMQStateMachine::IDLE);
|
fsm.CallStateChangeCallbacks(FairMQStateMachine::IDLE);
|
||||||
|
|
||||||
// start a worker thread to execute user states in.
|
|
||||||
fsm.fWorkerThread = thread(&Machine_::Worker, &fsm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Event, typename FSM>
|
template<typename Event, typename FSM>
|
||||||
|
@ -106,41 +187,23 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
LOG(state) << "Exiting FairMQ state machine";
|
LOG(state) << "Exiting FairMQ state machine";
|
||||||
}
|
}
|
||||||
|
|
||||||
// list of FSM states
|
|
||||||
struct OK_FSM : public msmf::state<> {};
|
|
||||||
struct ERROR_FSM : public msmf::terminate_state<> {};
|
|
||||||
|
|
||||||
struct IDLE_FSM : public msmf::state<> {};
|
|
||||||
struct INITIALIZING_DEVICE_FSM : public msmf::state<> {};
|
|
||||||
struct DEVICE_READY_FSM : public msmf::state<> {};
|
|
||||||
struct INITIALIZING_TASK_FSM : public msmf::state<> {};
|
|
||||||
struct READY_FSM : public msmf::state<> {};
|
|
||||||
struct RUNNING_FSM : public msmf::state<> {};
|
|
||||||
struct PAUSED_FSM : public msmf::state<> {};
|
|
||||||
struct RESETTING_TASK_FSM : public msmf::state<> {};
|
|
||||||
struct RESETTING_DEVICE_FSM : public msmf::state<> {};
|
|
||||||
struct EXITING_FSM : public msmf::state<> {};
|
|
||||||
|
|
||||||
// initial states
|
|
||||||
using initial_state = boost::mpl::vector<IDLE_FSM, OK_FSM>;
|
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
struct IdleFct
|
struct AutomaticFct
|
||||||
{
|
{
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
void operator()(EVT const&, FSM& fsm, SourceState& /* ss */, TargetState& ts)
|
||||||
{
|
{
|
||||||
LOG(state) << "Entering IDLE state";
|
fsm.fState = ts.Type();
|
||||||
fsm.fState = FairMQStateMachine::IDLE;
|
LOG(state) << "Entering " << ts.Name() << " state";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InitDeviceFct
|
struct InitDeviceFct
|
||||||
{
|
{
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
void operator()(EVT const&, FSM& fsm, SourceState& /* ss */, TargetState& ts)
|
||||||
{
|
{
|
||||||
fsm.fState = FairMQStateMachine::INITIALIZING_DEVICE;
|
fsm.fState = ts.Type();
|
||||||
|
|
||||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||||
while (fsm.fWorkActive)
|
while (fsm.fWorkActive)
|
||||||
|
@ -148,28 +211,18 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
fsm.fWorkDoneCondition.wait(lock);
|
fsm.fWorkDoneCondition.wait(lock);
|
||||||
}
|
}
|
||||||
fsm.fWorkAvailable = true;
|
fsm.fWorkAvailable = true;
|
||||||
LOG(state) << "Entering INITIALIZING DEVICE state";
|
LOG(state) << "Entering " << ts.Name() << " state";
|
||||||
fsm.fWork = fsm.fInitWrapperHandler;
|
fsm.fWork = fsm.fInitWrapperHandler;
|
||||||
fsm.fWorkAvailableCondition.notify_one();
|
fsm.fWorkAvailableCondition.notify_one();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DeviceReadyFct
|
|
||||||
{
|
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
|
||||||
{
|
|
||||||
LOG(state) << "Entering DEVICE READY state";
|
|
||||||
fsm.fState = FairMQStateMachine::DEVICE_READY;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InitTaskFct
|
struct InitTaskFct
|
||||||
{
|
{
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
void operator()(EVT const&, FSM& fsm, SourceState& /* ss */, TargetState& ts)
|
||||||
{
|
{
|
||||||
fsm.fState = FairMQStateMachine::INITIALIZING_TASK;
|
fsm.fState = ts.Type();
|
||||||
|
|
||||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||||
while (fsm.fWorkActive)
|
while (fsm.fWorkActive)
|
||||||
|
@ -177,28 +230,18 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
fsm.fWorkDoneCondition.wait(lock);
|
fsm.fWorkDoneCondition.wait(lock);
|
||||||
}
|
}
|
||||||
fsm.fWorkAvailable = true;
|
fsm.fWorkAvailable = true;
|
||||||
LOG(state) << "Entering INITIALIZING TASK state";
|
LOG(state) << "Entering " << ts.Name() << " state";
|
||||||
fsm.fWork = fsm.fInitTaskWrapperHandler;
|
fsm.fWork = fsm.fInitTaskWrapperHandler;
|
||||||
fsm.fWorkAvailableCondition.notify_one();
|
fsm.fWorkAvailableCondition.notify_one();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ReadyFct
|
|
||||||
{
|
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
|
||||||
{
|
|
||||||
LOG(state) << "Entering READY state";
|
|
||||||
fsm.fState = FairMQStateMachine::READY;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RunFct
|
struct RunFct
|
||||||
{
|
{
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
void operator()(EVT const&, FSM& fsm, SourceState& /* ss */, TargetState& ts)
|
||||||
{
|
{
|
||||||
fsm.fState = FairMQStateMachine::RUNNING;
|
fsm.fState = ts.Type();
|
||||||
|
|
||||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||||
while (fsm.fWorkActive)
|
while (fsm.fWorkActive)
|
||||||
|
@ -206,7 +249,7 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
fsm.fWorkDoneCondition.wait(lock);
|
fsm.fWorkDoneCondition.wait(lock);
|
||||||
}
|
}
|
||||||
fsm.fWorkAvailable = true;
|
fsm.fWorkAvailable = true;
|
||||||
LOG(state) << "Entering RUNNING state";
|
LOG(state) << "Entering " << ts.Name() << " state";
|
||||||
fsm.fWork = fsm.fRunWrapperHandler;
|
fsm.fWork = fsm.fRunWrapperHandler;
|
||||||
fsm.fWorkAvailableCondition.notify_one();
|
fsm.fWorkAvailableCondition.notify_one();
|
||||||
}
|
}
|
||||||
|
@ -215,9 +258,9 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
struct PauseFct
|
struct PauseFct
|
||||||
{
|
{
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
void operator()(EVT const&, FSM& fsm, SourceState& /* ss */, TargetState& ts)
|
||||||
{
|
{
|
||||||
fsm.fState = FairMQStateMachine::PAUSED;
|
fsm.fState = ts.Type();
|
||||||
|
|
||||||
fsm.fUnblockHandler();
|
fsm.fUnblockHandler();
|
||||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||||
|
@ -226,37 +269,18 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
fsm.fWorkDoneCondition.wait(lock);
|
fsm.fWorkDoneCondition.wait(lock);
|
||||||
}
|
}
|
||||||
fsm.fWorkAvailable = true;
|
fsm.fWorkAvailable = true;
|
||||||
LOG(state) << "Entering PAUSED state";
|
LOG(state) << "Entering " << ts.Name() << " state";
|
||||||
fsm.fWork = fsm.fPauseWrapperHandler;
|
fsm.fWork = fsm.fPauseWrapperHandler;
|
||||||
fsm.fWorkAvailableCondition.notify_one();
|
fsm.fWorkAvailableCondition.notify_one();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ResumeFct
|
|
||||||
{
|
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
|
||||||
{
|
|
||||||
fsm.fState = FairMQStateMachine::RUNNING;
|
|
||||||
|
|
||||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
|
||||||
while (fsm.fWorkActive)
|
|
||||||
{
|
|
||||||
fsm.fWorkDoneCondition.wait(lock);
|
|
||||||
}
|
|
||||||
fsm.fWorkAvailable = true;
|
|
||||||
LOG(state) << "Entering RUNNING state";
|
|
||||||
fsm.fWork = fsm.fRunWrapperHandler;
|
|
||||||
fsm.fWorkAvailableCondition.notify_one();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct StopFct
|
struct StopFct
|
||||||
{
|
{
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
void operator()(EVT const&, FSM& fsm, SourceState& /* ss */, TargetState& ts)
|
||||||
{
|
{
|
||||||
fsm.fState = FairMQStateMachine::READY;
|
fsm.fState = ts.Type();
|
||||||
|
|
||||||
fsm.fUnblockHandler();
|
fsm.fUnblockHandler();
|
||||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||||
|
@ -264,27 +288,27 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
{
|
{
|
||||||
fsm.fWorkDoneCondition.wait(lock);
|
fsm.fWorkDoneCondition.wait(lock);
|
||||||
}
|
}
|
||||||
LOG(state) << "Entering READY state";
|
LOG(state) << "Entering " << ts.Name() << " state";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InternalStopFct
|
struct InternalStopFct
|
||||||
{
|
{
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
void operator()(EVT const&, FSM& fsm, SourceState& /* ss */, TargetState& ts)
|
||||||
{
|
{
|
||||||
fsm.fState = FairMQStateMachine::READY;
|
fsm.fState = ts.Type();
|
||||||
fsm.fUnblockHandler();
|
fsm.fUnblockHandler();
|
||||||
LOG(state) << "RUNNING state finished without an external event, entering READY state";
|
LOG(state) << "RUNNING state finished without an external event, entering " << ts.Name() << " state";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ResetTaskFct
|
struct ResetTaskFct
|
||||||
{
|
{
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
void operator()(EVT const&, FSM& fsm, SourceState& /* ss */, TargetState& ts)
|
||||||
{
|
{
|
||||||
fsm.fState = FairMQStateMachine::RESETTING_TASK;
|
fsm.fState = ts.Type();
|
||||||
|
|
||||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||||
while (fsm.fWorkActive)
|
while (fsm.fWorkActive)
|
||||||
|
@ -292,7 +316,7 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
fsm.fWorkDoneCondition.wait(lock);
|
fsm.fWorkDoneCondition.wait(lock);
|
||||||
}
|
}
|
||||||
fsm.fWorkAvailable = true;
|
fsm.fWorkAvailable = true;
|
||||||
LOG(state) << "Entering RESETTING TASK state";
|
LOG(state) << "Entering " << ts.Name() << " state";
|
||||||
fsm.fWork = fsm.fResetTaskWrapperHandler;
|
fsm.fWork = fsm.fResetTaskWrapperHandler;
|
||||||
fsm.fWorkAvailableCondition.notify_one();
|
fsm.fWorkAvailableCondition.notify_one();
|
||||||
}
|
}
|
||||||
|
@ -301,9 +325,9 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
struct ResetDeviceFct
|
struct ResetDeviceFct
|
||||||
{
|
{
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
void operator()(EVT const&, FSM& fsm, SourceState& /* ss */, TargetState& ts)
|
||||||
{
|
{
|
||||||
fsm.fState = FairMQStateMachine::RESETTING_DEVICE;
|
fsm.fState = ts.Type();
|
||||||
|
|
||||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||||
while (fsm.fWorkActive)
|
while (fsm.fWorkActive)
|
||||||
|
@ -311,7 +335,7 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
fsm.fWorkDoneCondition.wait(lock);
|
fsm.fWorkDoneCondition.wait(lock);
|
||||||
}
|
}
|
||||||
fsm.fWorkAvailable = true;
|
fsm.fWorkAvailable = true;
|
||||||
LOG(state) << "Entering RESETTING DEVICE state";
|
LOG(state) << "Entering " << ts.Name() << " state";
|
||||||
fsm.fWork = fsm.fResetWrapperHandler;
|
fsm.fWork = fsm.fResetWrapperHandler;
|
||||||
fsm.fWorkAvailableCondition.notify_one();
|
fsm.fWorkAvailableCondition.notify_one();
|
||||||
}
|
}
|
||||||
|
@ -320,26 +344,19 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
struct ExitingFct
|
struct ExitingFct
|
||||||
{
|
{
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
void operator()(EVT const&, FSM& fsm, SourceState& /* ss */, TargetState& ts)
|
||||||
{
|
{
|
||||||
LOG(state) << "Entering EXITING state";
|
LOG(state) << "Entering " << ts.Name() << " state";
|
||||||
fsm.fState = FairMQStateMachine::EXITING;
|
fsm.fState = ts.Type();
|
||||||
fsm.fTerminationRequested = true;
|
|
||||||
fsm.CallStateChangeCallbacks(FairMQStateMachine::EXITING);
|
fsm.CallStateChangeCallbacks(FairMQStateMachine::EXITING);
|
||||||
|
|
||||||
// terminate worker thread
|
// Stop ProcessWork()
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fsm.fWorkMutex);
|
lock_guard<mutex> lock(fsm.fWorkMutex);
|
||||||
fsm.fWorkerTerminated = true;
|
fsm.fWorkerTerminated = true;
|
||||||
fsm.fWorkAvailableCondition.notify_one();
|
fsm.fWorkAvailableCondition.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
// join the worker thread (executing user states)
|
|
||||||
if (fsm.fWorkerThread.joinable())
|
|
||||||
{
|
|
||||||
fsm.fWorkerThread.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
fsm.fExitHandler();
|
fsm.fExitHandler();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -347,32 +364,32 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
struct ErrorFoundFct
|
struct ErrorFoundFct
|
||||||
{
|
{
|
||||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
void operator()(EVT const&, FSM& fsm, SourceState& /* ss */, TargetState& ts)
|
||||||
{
|
{
|
||||||
LOG(state) << "Entering ERROR state";
|
fsm.fState = ts.Type();
|
||||||
fsm.fState = FairMQStateMachine::Error;
|
LOG(state) << "Entering " << ts.Name() << " state";
|
||||||
fsm.CallStateChangeCallbacks(FairMQStateMachine::Error);
|
fsm.CallStateChangeCallbacks(FairMQStateMachine::Error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Transition table for Machine_
|
// Transition table for Machine_
|
||||||
struct transition_table : boost::mpl::vector<
|
struct transition_table : boost::mpl::vector<
|
||||||
// Start Event Next Action Guard
|
// Start Event Next Action Guard
|
||||||
msmf::Row<IDLE_FSM, INIT_DEVICE_E, INITIALIZING_DEVICE_FSM, InitDeviceFct, msmf::none>,
|
Row<IDLE_FSM_STATE, INIT_DEVICE_FSM_EVENT, INITIALIZING_DEVICE_FSM_STATE, InitDeviceFct, none>,
|
||||||
msmf::Row<IDLE_FSM, END_E, EXITING_FSM, ExitingFct, msmf::none>,
|
Row<IDLE_FSM_STATE, END_FSM_EVENT, EXITING_FSM_STATE, ExitingFct, none>,
|
||||||
msmf::Row<INITIALIZING_DEVICE_FSM, internal_DEVICE_READY_E, DEVICE_READY_FSM, DeviceReadyFct, msmf::none>,
|
Row<INITIALIZING_DEVICE_FSM_STATE, internal_DEVICE_READY_FSM_EVENT, DEVICE_READY_FSM_STATE, AutomaticFct, none>,
|
||||||
msmf::Row<DEVICE_READY_FSM, INIT_TASK_E, INITIALIZING_TASK_FSM, InitTaskFct, msmf::none>,
|
Row<DEVICE_READY_FSM_STATE, INIT_TASK_FSM_EVENT, INITIALIZING_TASK_FSM_STATE, InitTaskFct, none>,
|
||||||
msmf::Row<DEVICE_READY_FSM, RESET_DEVICE_E, RESETTING_DEVICE_FSM, ResetDeviceFct, msmf::none>,
|
Row<DEVICE_READY_FSM_STATE, RESET_DEVICE_FSM_EVENT, RESETTING_DEVICE_FSM_STATE, ResetDeviceFct, none>,
|
||||||
msmf::Row<INITIALIZING_TASK_FSM, internal_READY_E, READY_FSM, ReadyFct, msmf::none>,
|
Row<INITIALIZING_TASK_FSM_STATE, internal_READY_FSM_EVENT, READY_FSM_STATE, AutomaticFct, none>,
|
||||||
msmf::Row<READY_FSM, RUN_E, RUNNING_FSM, RunFct, msmf::none>,
|
Row<READY_FSM_STATE, RUN_FSM_EVENT, RUNNING_FSM_STATE, RunFct, none>,
|
||||||
msmf::Row<READY_FSM, RESET_TASK_E, RESETTING_TASK_FSM, ResetTaskFct, msmf::none>,
|
Row<READY_FSM_STATE, RESET_TASK_FSM_EVENT, RESETTING_TASK_FSM_STATE, ResetTaskFct, none>,
|
||||||
msmf::Row<RUNNING_FSM, PAUSE_E, PAUSED_FSM, PauseFct, msmf::none>,
|
Row<RUNNING_FSM_STATE, PAUSE_FSM_EVENT, PAUSED_FSM_STATE, PauseFct, none>,
|
||||||
msmf::Row<RUNNING_FSM, STOP_E, READY_FSM, StopFct, msmf::none>,
|
Row<RUNNING_FSM_STATE, STOP_FSM_EVENT, READY_FSM_STATE, StopFct, none>,
|
||||||
msmf::Row<RUNNING_FSM, internal_READY_E, READY_FSM, InternalStopFct, msmf::none>,
|
Row<RUNNING_FSM_STATE, internal_READY_FSM_EVENT, READY_FSM_STATE, InternalStopFct, none>,
|
||||||
msmf::Row<PAUSED_FSM, RUN_E, RUNNING_FSM, ResumeFct, msmf::none>,
|
Row<PAUSED_FSM_STATE, RUN_FSM_EVENT, RUNNING_FSM_STATE, RunFct, none>,
|
||||||
msmf::Row<RESETTING_TASK_FSM, internal_DEVICE_READY_E, DEVICE_READY_FSM, DeviceReadyFct, msmf::none>,
|
Row<RESETTING_TASK_FSM_STATE, internal_DEVICE_READY_FSM_EVENT, DEVICE_READY_FSM_STATE, AutomaticFct, none>,
|
||||||
msmf::Row<RESETTING_DEVICE_FSM, internal_IDLE_E, IDLE_FSM, IdleFct, msmf::none>,
|
Row<RESETTING_DEVICE_FSM_STATE, internal_IDLE_FSM_EVENT, IDLE_FSM_STATE, AutomaticFct, none>,
|
||||||
msmf::Row<OK_FSM, ERROR_FOUND_E, ERROR_FSM, ErrorFoundFct, msmf::none>>
|
Row<OK_FSM_STATE, ERROR_FOUND_FSM_EVENT, ERROR_FSM_STATE, ErrorFoundFct, none>>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
// replaces the default no-transition response.
|
// replaces the default no-transition response.
|
||||||
|
@ -391,45 +408,12 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
if (pos != string::npos)
|
if (pos != string::npos)
|
||||||
{
|
{
|
||||||
stateName = stateName.substr(pos + 1);
|
stateName = stateName.substr(pos + 1);
|
||||||
stateName = stateName.substr(0, stateName.size() - 4);
|
stateName = stateName.substr(0, stateName.size() - 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stateName != "OK")
|
if (stateName != "OK")
|
||||||
{
|
{
|
||||||
LOG(state) << "No transition from state " << stateName << " on event " << e.name();
|
LOG(state) << "No transition from state " << stateName << " on event " << e.Name();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static string GetStateName(const int state)
|
|
||||||
{
|
|
||||||
switch(state)
|
|
||||||
{
|
|
||||||
case FairMQStateMachine::OK:
|
|
||||||
return "OK";
|
|
||||||
case FairMQStateMachine::Error:
|
|
||||||
return "Error";
|
|
||||||
case FairMQStateMachine::IDLE:
|
|
||||||
return "IDLE";
|
|
||||||
case FairMQStateMachine::INITIALIZING_DEVICE:
|
|
||||||
return "INITIALIZING_DEVICE";
|
|
||||||
case FairMQStateMachine::DEVICE_READY:
|
|
||||||
return "DEVICE_READY";
|
|
||||||
case FairMQStateMachine::INITIALIZING_TASK:
|
|
||||||
return "INITIALIZING_TASK";
|
|
||||||
case FairMQStateMachine::READY:
|
|
||||||
return "READY";
|
|
||||||
case FairMQStateMachine::RUNNING:
|
|
||||||
return "RUNNING";
|
|
||||||
case FairMQStateMachine::PAUSED:
|
|
||||||
return "PAUSED";
|
|
||||||
case FairMQStateMachine::RESETTING_TASK:
|
|
||||||
return "RESETTING_TASK";
|
|
||||||
case FairMQStateMachine::RESETTING_DEVICE:
|
|
||||||
return "RESETTING_DEVICE";
|
|
||||||
case FairMQStateMachine::EXITING:
|
|
||||||
return "EXITING";
|
|
||||||
default:
|
|
||||||
return "requested name for non-existent state...";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,12 +445,10 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
|
|
||||||
boost::signals2::signal<void(const FairMQStateMachine::State)> fStateChangeSignal;
|
boost::signals2::signal<void(const FairMQStateMachine::State)> fStateChangeSignal;
|
||||||
unordered_map<string, boost::signals2::connection> fStateChangeSignalsMap;
|
unordered_map<string, boost::signals2::connection> fStateChangeSignalsMap;
|
||||||
atomic<bool> fTerminationRequested;
|
|
||||||
|
|
||||||
atomic<FairMQStateMachine::State> fState;
|
atomic<FairMQStateMachine::State> fState;
|
||||||
|
|
||||||
private:
|
void ProcessWork()
|
||||||
void Worker()
|
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -475,7 +457,7 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
// Wait for work to be done.
|
// Wait for work to be done.
|
||||||
while (!fWorkAvailable && !fWorkerTerminated)
|
while (!fWorkAvailable && !fWorkerTerminated)
|
||||||
{
|
{
|
||||||
fWorkAvailableCondition.wait(lock);
|
fWorkAvailableCondition.wait_for(lock, chrono::milliseconds(300));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fWorkerTerminated)
|
if (fWorkerTerminated)
|
||||||
|
@ -497,20 +479,10 @@ struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||||
CallStateChangeCallbacks(fState);
|
CallStateChangeCallbacks(fState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// run state handlers in a separate thread
|
|
||||||
thread fWorkerThread;
|
|
||||||
}; // Machine_
|
}; // Machine_
|
||||||
|
|
||||||
using FairMQFSM = boost::msm::back::state_machine<Machine_>;
|
using FairMQFSM = boost::msm::back::state_machine<Machine_>;
|
||||||
|
|
||||||
// reactivate the warning for non-virtual destructor
|
|
||||||
#if defined(__clang__)
|
|
||||||
_Pragma("clang diagnostic pop")
|
|
||||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
|
||||||
_Pragma("GCC diagnostic pop")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace fsm
|
} // namespace fsm
|
||||||
} // namespace mq
|
} // namespace mq
|
||||||
} // namespace fair
|
} // namespace fair
|
||||||
|
@ -552,79 +524,79 @@ bool FairMQStateMachine::ChangeState(int event)
|
||||||
case INIT_DEVICE:
|
case INIT_DEVICE:
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fChangeStateMutex);
|
lock_guard<mutex> lock(fChangeStateMutex);
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(INIT_DEVICE_E());
|
static_pointer_cast<FairMQFSM>(fFsm)->process_event(INIT_DEVICE_FSM_EVENT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case internal_DEVICE_READY:
|
case internal_DEVICE_READY:
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fChangeStateMutex);
|
lock_guard<mutex> lock(fChangeStateMutex);
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(internal_DEVICE_READY_E());
|
static_pointer_cast<FairMQFSM>(fFsm)->process_event(internal_DEVICE_READY_FSM_EVENT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case INIT_TASK:
|
case INIT_TASK:
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fChangeStateMutex);
|
lock_guard<mutex> lock(fChangeStateMutex);
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(INIT_TASK_E());
|
static_pointer_cast<FairMQFSM>(fFsm)->process_event(INIT_TASK_FSM_EVENT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case internal_READY:
|
case internal_READY:
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fChangeStateMutex);
|
lock_guard<mutex> lock(fChangeStateMutex);
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(internal_READY_E());
|
static_pointer_cast<FairMQFSM>(fFsm)->process_event(internal_READY_FSM_EVENT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case RUN:
|
case RUN:
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fChangeStateMutex);
|
lock_guard<mutex> lock(fChangeStateMutex);
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(RUN_E());
|
static_pointer_cast<FairMQFSM>(fFsm)->process_event(RUN_FSM_EVENT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case PAUSE:
|
case PAUSE:
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fChangeStateMutex);
|
lock_guard<mutex> lock(fChangeStateMutex);
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(PAUSE_E());
|
static_pointer_cast<FairMQFSM>(fFsm)->process_event(PAUSE_FSM_EVENT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case STOP:
|
case STOP:
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fChangeStateMutex);
|
lock_guard<mutex> lock(fChangeStateMutex);
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(STOP_E());
|
static_pointer_cast<FairMQFSM>(fFsm)->process_event(STOP_FSM_EVENT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case RESET_DEVICE:
|
case RESET_DEVICE:
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fChangeStateMutex);
|
lock_guard<mutex> lock(fChangeStateMutex);
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(RESET_DEVICE_E());
|
static_pointer_cast<FairMQFSM>(fFsm)->process_event(RESET_DEVICE_FSM_EVENT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case RESET_TASK:
|
case RESET_TASK:
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fChangeStateMutex);
|
lock_guard<mutex> lock(fChangeStateMutex);
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(RESET_TASK_E());
|
static_pointer_cast<FairMQFSM>(fFsm)->process_event(RESET_TASK_FSM_EVENT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case internal_IDLE:
|
case internal_IDLE:
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fChangeStateMutex);
|
lock_guard<mutex> lock(fChangeStateMutex);
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(internal_IDLE_E());
|
static_pointer_cast<FairMQFSM>(fFsm)->process_event(internal_IDLE_FSM_EVENT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case END:
|
case END:
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fChangeStateMutex);
|
lock_guard<mutex> lock(fChangeStateMutex);
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(END_E());
|
static_pointer_cast<FairMQFSM>(fFsm)->process_event(END_FSM_EVENT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case ERROR_FOUND:
|
case ERROR_FOUND:
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(fChangeStateMutex);
|
lock_guard<mutex> lock(fChangeStateMutex);
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(ERROR_FOUND_E());
|
static_pointer_cast<FairMQFSM>(fFsm)->process_event(ERROR_FOUND_FSM_EVENT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
LOG(error) << "Requested state transition with an unsupported event: " << event << endl
|
LOG(error) << "Requested state transition with an unsupported event: " << event << endl
|
||||||
<< "Supported are: INIT_DEVICE, INIT_TASK, RUN, PAUSE, STOP, RESET_TASK, RESET_DEVICE, END, ERROR_FOUND";
|
<< "Supported are: INIT_DEVICE, INIT_TASK, RUN, PAUSE, STOP, RESET_TASK, RESET_DEVICE, END, ERROR_FOUND";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -738,7 +710,11 @@ void FairMQStateMachine::CallStateChangeCallbacks(const State state) const
|
||||||
|
|
||||||
string FairMQStateMachine::GetCurrentStateName() const
|
string FairMQStateMachine::GetCurrentStateName() const
|
||||||
{
|
{
|
||||||
return static_pointer_cast<FairMQFSM>(fFsm)->GetStateName(static_pointer_cast<FairMQFSM>(fFsm)->fState);
|
return GetStateName(static_pointer_cast<FairMQFSM>(fFsm)->fState);
|
||||||
|
}
|
||||||
|
string FairMQStateMachine::GetStateName(const State state)
|
||||||
|
{
|
||||||
|
return stateNames.at(state);
|
||||||
}
|
}
|
||||||
int FairMQStateMachine::GetCurrentState() const
|
int FairMQStateMachine::GetCurrentState() const
|
||||||
{
|
{
|
||||||
|
@ -753,23 +729,12 @@ bool FairMQStateMachine::CheckCurrentState(string state) const
|
||||||
return state == GetCurrentStateName();
|
return state == GetCurrentStateName();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FairMQStateMachine::Terminated()
|
void FairMQStateMachine::ProcessWork()
|
||||||
{
|
{
|
||||||
return static_pointer_cast<FairMQFSM>(fFsm)->fTerminationRequested;
|
static_pointer_cast<FairMQFSM>(fFsm)->ProcessWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
int FairMQStateMachine::GetEventNumber(const string& event)
|
int FairMQStateMachine::GetEventNumber(const string& event)
|
||||||
{
|
{
|
||||||
if (event == "INIT_DEVICE") return INIT_DEVICE;
|
return eventNumbers.at(event);
|
||||||
if (event == "INIT_TASK") return INIT_TASK;
|
|
||||||
if (event == "RUN") return RUN;
|
|
||||||
if (event == "PAUSE") return PAUSE;
|
|
||||||
if (event == "STOP") return STOP;
|
|
||||||
if (event == "RESET_DEVICE") return RESET_DEVICE;
|
|
||||||
if (event == "RESET_TASK") return RESET_TASK;
|
|
||||||
if (event == "END") return END;
|
|
||||||
if (event == "ERROR_FOUND") return ERROR_FOUND;
|
|
||||||
LOG(error) << "Requested number for non-existent event... " << event << endl
|
|
||||||
<< "Supported are: INIT_DEVICE, INIT_TASK, RUN, PAUSE, STOP, RESET_DEVICE, RESET_TASK, END, ERROR_FOUND";
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,10 +79,10 @@ class FairMQStateMachine
|
||||||
void CallStateChangeCallbacks(const State state) const;
|
void CallStateChangeCallbacks(const State state) const;
|
||||||
|
|
||||||
std::string GetCurrentStateName() const;
|
std::string GetCurrentStateName() const;
|
||||||
|
static std::string GetStateName(const State);
|
||||||
int GetCurrentState() const;
|
int GetCurrentState() const;
|
||||||
bool CheckCurrentState(int state) const;
|
bool CheckCurrentState(int state) const;
|
||||||
bool CheckCurrentState(std::string state) const;
|
bool CheckCurrentState(std::string state) const;
|
||||||
bool Terminated();
|
|
||||||
|
|
||||||
// actions to be overwritten by derived classes
|
// actions to be overwritten by derived classes
|
||||||
virtual void InitWrapper() {}
|
virtual void InitWrapper() {}
|
||||||
|
@ -94,8 +94,10 @@ class FairMQStateMachine
|
||||||
virtual void Exit() {}
|
virtual void Exit() {}
|
||||||
virtual void Unblock() {}
|
virtual void Unblock() {}
|
||||||
|
|
||||||
|
void ProcessWork();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int GetEventNumber(const std::string& event);
|
static int GetEventNumber(const std::string& event);
|
||||||
|
|
||||||
std::mutex fChangeStateMutex;
|
std::mutex fChangeStateMutex;
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,11 @@ class PluginManager
|
||||||
|
|
||||||
PluginManager();
|
PluginManager();
|
||||||
|
|
||||||
|
~PluginManager()
|
||||||
|
{
|
||||||
|
LOG(debug) << "Shutting down Plugin Manager";
|
||||||
|
}
|
||||||
|
|
||||||
auto SetSearchPaths(const std::vector<boost::filesystem::path>&) -> void;
|
auto SetSearchPaths(const std::vector<boost::filesystem::path>&) -> void;
|
||||||
auto AppendSearchPath(const boost::filesystem::path&) -> void;
|
auto AppendSearchPath(const boost::filesystem::path&) -> void;
|
||||||
auto PrependSearchPath(const boost::filesystem::path&) -> void;
|
auto PrependSearchPath(const boost::filesystem::path&) -> void;
|
||||||
|
|
|
@ -47,6 +47,11 @@ class PluginServices
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~PluginServices()
|
||||||
|
{
|
||||||
|
LOG(debug) << "Shutting down Plugin Services";
|
||||||
|
}
|
||||||
|
|
||||||
PluginServices(const PluginServices&) = delete;
|
PluginServices(const PluginServices&) = delete;
|
||||||
PluginServices operator=(const PluginServices&) = delete;
|
PluginServices operator=(const PluginServices&) = delete;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
#include <future> // std::async, std::future
|
#include <future> // std::async, std::future
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -19,6 +20,24 @@ namespace
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
void control(FairMQDevice& device)
|
||||||
|
{
|
||||||
|
device.ChangeState("INIT_DEVICE");
|
||||||
|
device.WaitForEndOfState("INIT_DEVICE");
|
||||||
|
device.ChangeState("INIT_TASK");
|
||||||
|
device.WaitForEndOfState("INIT_TASK");
|
||||||
|
|
||||||
|
device.ChangeState("RUN");
|
||||||
|
device.WaitForEndOfState("RUN");
|
||||||
|
|
||||||
|
device.ChangeState("RESET_TASK");
|
||||||
|
device.WaitForEndOfState("RESET_TASK");
|
||||||
|
device.ChangeState("RESET_DEVICE");
|
||||||
|
device.WaitForEndOfState("RESET_DEVICE");
|
||||||
|
|
||||||
|
device.ChangeState("END");
|
||||||
|
}
|
||||||
|
|
||||||
class MultipleDevices : public ::testing::Test {
|
class MultipleDevices : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
MultipleDevices()
|
MultipleDevices()
|
||||||
|
@ -34,20 +53,14 @@ class MultipleDevices : public ::testing::Test {
|
||||||
channel.UpdateRateLogging(0);
|
channel.UpdateRateLogging(0);
|
||||||
sender.fChannels["data"].push_back(channel);
|
sender.fChannels["data"].push_back(channel);
|
||||||
|
|
||||||
sender.ChangeState("INIT_DEVICE");
|
thread t(control, std::ref(sender));
|
||||||
sender.WaitForEndOfState("INIT_DEVICE");
|
|
||||||
sender.ChangeState("INIT_TASK");
|
|
||||||
sender.WaitForEndOfState("INIT_TASK");
|
|
||||||
|
|
||||||
sender.ChangeState("RUN");
|
sender.RunStateMachine();
|
||||||
sender.WaitForEndOfState("RUN");
|
|
||||||
|
|
||||||
sender.ChangeState("RESET_TASK");
|
if (t.joinable())
|
||||||
sender.WaitForEndOfState("RESET_TASK");
|
{
|
||||||
sender.ChangeState("RESET_DEVICE");
|
t.join();
|
||||||
sender.WaitForEndOfState("RESET_DEVICE");
|
}
|
||||||
|
|
||||||
sender.ChangeState("END");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -62,20 +75,14 @@ class MultipleDevices : public ::testing::Test {
|
||||||
channel.UpdateRateLogging(0);
|
channel.UpdateRateLogging(0);
|
||||||
receiver.fChannels["data"].push_back(channel);
|
receiver.fChannels["data"].push_back(channel);
|
||||||
|
|
||||||
receiver.ChangeState("INIT_DEVICE");
|
thread t(control, std::ref(receiver));
|
||||||
receiver.WaitForEndOfState("INIT_DEVICE");
|
|
||||||
receiver.ChangeState("INIT_TASK");
|
|
||||||
receiver.WaitForEndOfState("INIT_TASK");
|
|
||||||
|
|
||||||
receiver.ChangeState("RUN");
|
receiver.RunStateMachine();
|
||||||
receiver.WaitForEndOfState("RUN");
|
|
||||||
|
|
||||||
receiver.ChangeState("RESET_TASK");
|
if (t.joinable())
|
||||||
receiver.WaitForEndOfState("RESET_TASK");
|
{
|
||||||
receiver.ChangeState("RESET_DEVICE");
|
t.join();
|
||||||
receiver.WaitForEndOfState("RESET_DEVICE");
|
}
|
||||||
|
|
||||||
receiver.ChangeState("END");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <FairMQDevice.h>
|
#include <FairMQDevice.h>
|
||||||
#include <options/FairMQProgOptions.h>
|
#include <options/FairMQProgOptions.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
namespace fair
|
namespace fair
|
||||||
{
|
{
|
||||||
|
@ -36,21 +37,28 @@ inline auto control(std::shared_ptr<FairMQDevice> device) -> void
|
||||||
|
|
||||||
struct PluginServices : ::testing::Test {
|
struct PluginServices : ::testing::Test {
|
||||||
PluginServices()
|
PluginServices()
|
||||||
: mConfig()
|
: mConfig()
|
||||||
, mDevice{std::make_shared<FairMQDevice>()}
|
, mDevice{std::make_shared<FairMQDevice>()}
|
||||||
, mServices{&mConfig, mDevice}
|
, mServices{&mConfig, mDevice}
|
||||||
|
, fRunStateMachineThread()
|
||||||
{
|
{
|
||||||
|
fRunStateMachineThread = std::thread(&FairMQDevice::RunStateMachine, mDevice.get());
|
||||||
mDevice->SetTransport("zeromq");
|
mDevice->SetTransport("zeromq");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~PluginServices()
|
~PluginServices()
|
||||||
{
|
{
|
||||||
if(mDevice->GetCurrentState() == FairMQDevice::IDLE) control(mDevice);
|
if (mDevice->GetCurrentState() == FairMQDevice::IDLE) control(mDevice);
|
||||||
|
if (fRunStateMachineThread.joinable()) {
|
||||||
|
fRunStateMachineThread.join();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FairMQProgOptions mConfig;
|
FairMQProgOptions mConfig;
|
||||||
std::shared_ptr<FairMQDevice> mDevice;
|
std::shared_ptr<FairMQDevice> mDevice;
|
||||||
fair::mq::PluginServices mServices;
|
fair::mq::PluginServices mServices;
|
||||||
|
std::thread fRunStateMachineThread;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace test */
|
} /* namespace test */
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -38,7 +39,7 @@ auto control(shared_ptr<FairMQDevice> device) -> void
|
||||||
|
|
||||||
TEST(Plugin, Operators)
|
TEST(Plugin, Operators)
|
||||||
{
|
{
|
||||||
FairMQProgOptions config{};
|
FairMQProgOptions config;
|
||||||
auto device = make_shared<FairMQDevice>();
|
auto device = make_shared<FairMQDevice>();
|
||||||
PluginServices services{&config, device};
|
PluginServices services{&config, device};
|
||||||
Plugin p1{"dds", {1, 0, 0}, "Foo Bar <foo.bar@test.net>", "https://git.test.net/dds.git", &services};
|
Plugin p1{"dds", {1, 0, 0}, "Foo Bar <foo.bar@test.net>", "https://git.test.net/dds.git", &services};
|
||||||
|
@ -46,19 +47,27 @@ TEST(Plugin, Operators)
|
||||||
Plugin p3{"file", {1, 0, 0}, "Foo Bar <foo.bar@test.net>", "https://git.test.net/file.git", &services};
|
Plugin p3{"file", {1, 0, 0}, "Foo Bar <foo.bar@test.net>", "https://git.test.net/file.git", &services};
|
||||||
EXPECT_EQ(p1, p2);
|
EXPECT_EQ(p1, p2);
|
||||||
EXPECT_NE(p1, p3);
|
EXPECT_NE(p1, p3);
|
||||||
control(device);
|
thread t(control, device);
|
||||||
|
device->RunStateMachine();
|
||||||
|
if (t.joinable()) {
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Plugin, OstreamOperators)
|
TEST(Plugin, OstreamOperators)
|
||||||
{
|
{
|
||||||
FairMQProgOptions config{};
|
FairMQProgOptions config;
|
||||||
auto device = make_shared<FairMQDevice>();
|
auto device = make_shared<FairMQDevice>();
|
||||||
PluginServices services{&config, device};
|
PluginServices services{&config, device};
|
||||||
Plugin p1{"dds", {1, 0, 0}, "Foo Bar <foo.bar@test.net>", "https://git.test.net/dds.git", &services};
|
Plugin p1{"dds", {1, 0, 0}, "Foo Bar <foo.bar@test.net>", "https://git.test.net/dds.git", &services};
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << p1;
|
ss << p1;
|
||||||
EXPECT_EQ(ss.str(), string{"'dds', version '1.0.0', maintainer 'Foo Bar <foo.bar@test.net>', homepage 'https://git.test.net/dds.git'"});
|
EXPECT_EQ(ss.str(), string{"'dds', version '1.0.0', maintainer 'Foo Bar <foo.bar@test.net>', homepage 'https://git.test.net/dds.git'"});
|
||||||
control(device);
|
thread t(control, device);
|
||||||
|
device->RunStateMachine();
|
||||||
|
if (t.joinable()) {
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PluginVersion, Operators)
|
TEST(PluginVersion, Operators)
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -39,8 +40,8 @@ auto control(shared_ptr<FairMQDevice> device) -> void
|
||||||
|
|
||||||
TEST(PluginManager, LoadPluginDynamic)
|
TEST(PluginManager, LoadPluginDynamic)
|
||||||
{
|
{
|
||||||
FairMQProgOptions config{};
|
FairMQProgOptions config;
|
||||||
auto mgr = PluginManager{};
|
PluginManager mgr;
|
||||||
auto device = make_shared<FairMQDevice>();
|
auto device = make_shared<FairMQDevice>();
|
||||||
mgr.EmplacePluginServices(&config, device);
|
mgr.EmplacePluginServices(&config, device);
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ TEST(PluginManager, LoadPluginDynamic)
|
||||||
|
|
||||||
// check order
|
// check order
|
||||||
const auto expected = vector<string>{"test_dummy", "test_dummy2"};
|
const auto expected = vector<string>{"test_dummy", "test_dummy2"};
|
||||||
auto actual = vector<string>{};
|
auto actual = vector<string>();
|
||||||
mgr.ForEachPlugin([&](Plugin& plugin){ actual.push_back(plugin.GetName()); });
|
mgr.ForEachPlugin([&](Plugin& plugin){ actual.push_back(plugin.GetName()); });
|
||||||
ASSERT_TRUE(actual == expected);
|
ASSERT_TRUE(actual == expected);
|
||||||
|
|
||||||
|
@ -62,18 +63,22 @@ TEST(PluginManager, LoadPluginDynamic)
|
||||||
mgr.ForEachPluginProgOptions([&count](const options_description& /*d*/){ ++count; });
|
mgr.ForEachPluginProgOptions([&count](const options_description& /*d*/){ ++count; });
|
||||||
ASSERT_EQ(count, 1);
|
ASSERT_EQ(count, 1);
|
||||||
|
|
||||||
control(device);
|
thread t(control, device);
|
||||||
|
device->RunStateMachine();
|
||||||
|
if (t.joinable()) {
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PluginManager, LoadPluginStatic)
|
TEST(PluginManager, LoadPluginStatic)
|
||||||
{
|
{
|
||||||
auto mgr = PluginManager{};
|
PluginManager mgr;
|
||||||
auto device = make_shared<FairMQDevice>();
|
auto device = make_shared<FairMQDevice>();
|
||||||
device->SetTransport("zeromq");
|
device->SetTransport("zeromq");
|
||||||
|
|
||||||
ASSERT_NO_THROW(mgr.LoadPlugin("s:control"));
|
ASSERT_NO_THROW(mgr.LoadPlugin("s:control"));
|
||||||
|
|
||||||
FairMQProgOptions config{};
|
FairMQProgOptions config;
|
||||||
config.SetValue<string>("control", "static");
|
config.SetValue<string>("control", "static");
|
||||||
config.SetValue("catch-signals", 0);
|
config.SetValue("catch-signals", 0);
|
||||||
mgr.EmplacePluginServices(&config, device);
|
mgr.EmplacePluginServices(&config, device);
|
||||||
|
@ -82,7 +87,7 @@ TEST(PluginManager, LoadPluginStatic)
|
||||||
|
|
||||||
// check order
|
// check order
|
||||||
const auto expected = vector<string>{"control"};
|
const auto expected = vector<string>{"control"};
|
||||||
auto actual = vector<string>{};
|
auto actual = vector<string>();
|
||||||
mgr.ForEachPlugin([&](Plugin& plugin){ actual.push_back(plugin.GetName()); });
|
mgr.ForEachPlugin([&](Plugin& plugin){ actual.push_back(plugin.GetName()); });
|
||||||
ASSERT_TRUE(actual == expected);
|
ASSERT_TRUE(actual == expected);
|
||||||
|
|
||||||
|
@ -91,6 +96,8 @@ TEST(PluginManager, LoadPluginStatic)
|
||||||
mgr.ForEachPluginProgOptions([&count](const options_description&){ ++count; });
|
mgr.ForEachPluginProgOptions([&count](const options_description&){ ++count; });
|
||||||
ASSERT_EQ(count, 1);
|
ASSERT_EQ(count, 1);
|
||||||
|
|
||||||
|
device->RunStateMachine();
|
||||||
|
|
||||||
mgr.WaitForPluginsToReleaseDeviceControl();
|
mgr.WaitForPluginsToReleaseDeviceControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +119,7 @@ TEST(PluginManager, SearchPathValidation)
|
||||||
const auto path1 = path{"/tmp/test1"};
|
const auto path1 = path{"/tmp/test1"};
|
||||||
const auto path2 = path{"/tmp/test2"};
|
const auto path2 = path{"/tmp/test2"};
|
||||||
const auto path3 = path{"/tmp/test3"};
|
const auto path3 = path{"/tmp/test3"};
|
||||||
auto mgr = PluginManager{};
|
PluginManager mgr;
|
||||||
|
|
||||||
mgr.SetSearchPaths({path1, path2});
|
mgr.SetSearchPaths({path1, path2});
|
||||||
auto expected = vector<path>{path1, path2};
|
auto expected = vector<path>{path1, path2};
|
||||||
|
@ -140,7 +147,7 @@ TEST(PluginManager, SearchPaths)
|
||||||
fs.close();
|
fs.close();
|
||||||
const auto empty_path = path{""};
|
const auto empty_path = path{""};
|
||||||
|
|
||||||
auto mgr = PluginManager{};
|
PluginManager mgr;
|
||||||
ASSERT_NO_THROW(mgr.AppendSearchPath(non_existing_dir));
|
ASSERT_NO_THROW(mgr.AppendSearchPath(non_existing_dir));
|
||||||
ASSERT_NO_THROW(mgr.AppendSearchPath(existing_dir));
|
ASSERT_NO_THROW(mgr.AppendSearchPath(existing_dir));
|
||||||
ASSERT_THROW(mgr.AppendSearchPath(existing_file), PluginManager::BadSearchPath);
|
ASSERT_THROW(mgr.AppendSearchPath(existing_file), PluginManager::BadSearchPath);
|
||||||
|
|
|
@ -17,7 +17,7 @@ using namespace std;
|
||||||
|
|
||||||
TEST(PluginManager, LoadPluginPrelinkedDynamic)
|
TEST(PluginManager, LoadPluginPrelinkedDynamic)
|
||||||
{
|
{
|
||||||
auto mgr = PluginManager{};
|
PluginManager mgr;
|
||||||
|
|
||||||
ASSERT_NO_THROW(mgr.LoadPlugin("p:test_dummy"));
|
ASSERT_NO_THROW(mgr.LoadPlugin("p:test_dummy"));
|
||||||
ASSERT_NO_THROW(mgr.LoadPlugin("p:test_dummy2"));
|
ASSERT_NO_THROW(mgr.LoadPlugin("p:test_dummy2"));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user