Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
StateFlow.cxx
Go to the documentation of this file.
1
35#include <climits>
36
38
40
42 : StateFlowBase(service)
43 , queueSize_(0)
44 , currentMessage_(nullptr)
45 , currentPriority_(MAX_PRIORITY_)
46 , isWaiting_(1)
47{
48 reset_flow(STATE(wait_for_message));
49}
50
51StateFlowWithQueue::~StateFlowWithQueue()
52{
53}
54
55
59{
61 do
62 {
63 Action action = (this->*state_)();
64 if (!action.next_state())
65 {
66 // This action is == wait(). This means we are blocked or asked to
67 // yield.
68 return;
69 }
70 state_ = action.next_state();
71 } while (1);
72}
73
74StateFlowBase::Action StateFlowWithQueue::wait_for_message()
75{
76 AtomicHolder h(this);
77 unsigned priority;
80 {
81 isWaiting_ = 0;
83 queueSize_--;
84 // Yielding here will ensure that we are processing the next message on
85 // the current executor according to its priority.
86 return yield_and_call(STATE(entry));
87 }
88 else
89 {
90 isWaiting_ = 1;
91 queueSize_ = 0;
93 return wait();
94 }
95}
96
98{
99 service()->executor()->add(this);
100}
101
102#if OPENMRN_FEATURE_RTOS_FROM_ISR
103void StateFlowBase::notify_from_isr()
104{
105 service()->executor()->add_from_isr(this, 0);
106}
107#endif // OPENMRN_FEATURE_RTOS_FROM_ISR
108
113
114#if OPENMRN_FEATURE_RTOS_FROM_ISR
115void StateFlowWithQueue::notify_from_isr()
116{
117 service()->executor()->add_from_isr(this, currentPriority_);
118}
119#endif // OPENMRN_FEATURE_RTOS_FROM_ISR
120
#define STATE(_fn)
Turns a function name into an argument to be supplied to functions expecting a state.
Definition StateFlow.hxx:61
See OSMutexLock in os/OS.hxx.
Definition Atomic.hxx:153
Abstract base class for all Buffers.
Definition Buffer.hxx:85
virtual void add(Executable *action, unsigned priority=UINT_MAX)=0
Send a message to this Executor's queue.
Collection of related state machines that pend on incoming messages.
ExecutorBase * executor()
Return type for a state flow callback.
Callback next_state()
Get the next state for the StateFlowAction.
Base class for state machines.
Action yield_and_call(Callback c)
Place the current flow to the back of the executor, and transition to a new state after we get the CP...
Service * service()
Return a pointer to the service I am bound to.
void run() override
Callback from the executor.
Definition StateFlow.cxx:58
void notify() override
Wakeup call arrived.
Definition StateFlow.cxx:97
Callback state_
current active state in the flow
Action wait()
Wait for an asynchronous call.
void reset_flow(Callback c)
Resets the flow to the specified state.
Action terminated()
Terminates the current StateFlow activity.
virtual QMember * queue_next(unsigned *priority)=0
Takes the front entry in the queue.
unsigned isWaiting_
True if we are in the pending state, waiting for an entry to show up in the queue.
void notify() override
Wakeup call arrived. Schedules *this on the executor.
StateFlowWithQueue(Service *service)
Constructor.
Definition StateFlow.cxx:41
BufferBase * currentMessage_
Message we are currently processing.
static const unsigned MAX_PRIORITY_
Largest acceptable priority value for a stateflow.
unsigned currentPriority_
Priority of the current message we are processing.
virtual Action entry()=0
Entry into the StateFlow activity.
unsigned queueSize_
For debugging: how many entries are currently waiting in the queue of this stateflow.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138