Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
StateFlowBase Class Reference

Base class for state machines. More...

#include <StateFlow.hxx>

Inheritance diagram for StateFlowBase:
Executable Notifiable QMember Destructable AutoSyncFileFlow BlinkerFlow Bus< MessageType >::Master Console::CommandFlow Console::Session CpuDisplay DirectHubImpl< T > DirectHubPortSelect DirectHubPortSelect::DirectHubReadFlow EepromTimerFlow ExecutorWatchdog HubDeviceSelectReadFlow< HFlow > PoolToQueueFlow< T > SocketClient StateFlowWithQueue dcc::DccDecodeFlow dcc::LogonHandler< Module > dcc::LogonHandler< Module >::LogonSelect openlcb::AMEGlobalQueryHandler openlcb::BLEHubPort openlcb::BLEHubPort::InputFlow openlcb::BroadcastTime openlcb::BroadcastTimeAlarm openlcb::ConfigUpdateFlow openlcb::DatagramClientImpl openlcb::EventIdentifyGlobal openlcb::FdToTcpParser openlcb::MemorySpaceStreamReadFlow openlcb::PIPClient openlcb::RefreshLoop openlcb::ReinitAllNodes openlcb::TractionCvSpace openmrn_arduino::Esp32WiFiManager::WiFiStackFlow traction_modem::RxFlow withrottle::ThrottleFlow

Classes

class  Action
 Return type for a state flow callback. More...
 
struct  StateFlowSelectHelper
 Use this class to read from an fd using select() in a state flow. More...
 
struct  StateFlowTimedSelectHelper
 Use this class to read from an fd with select and timeout. More...
 
class  StateFlowTimer
 Use this timer class to deliver the timeout notification to a stateflow. More...
 

Public Member Functions

void run () override
 Callback from the executor.
 
void notify () override
 Wakeup call arrived.
 
Serviceservice ()
 Return a pointer to the service I am bound to.
 
- Public Member Functions inherited from Executable
void test_deletion ()
 
- Public Member Functions inherited from QMember
void init ()
 Initiailize a QMember, in place of a public placement construction.
 

Static Public Member Functions

template<class T , typename... Args>
static void invoke_subflow_and_ignore_result (FlowInterface< Buffer< T > > *target_flow, Args &&... args)
 Calls a helper flow to perform some actions.
 

Protected Types

typedef Action(StateFlowBase::* Callback) ()
 State Flow callback prototype.
 

Protected Member Functions

 StateFlowBase (Service *service)
 Constructor.
 
 ~StateFlowBase ()
 Destructor.
 
void reset_flow (Callback c)
 Resets the flow to the specified state.
 
bool is_state (Callback c)
 
bool is_terminated ()
 
void start_flow (Callback c)
 Resets the flow to the specified state and starts it.
 
Action again ()
 Call the current state again via call_immediately.
 
Action exit ()
 Terminate current StateFlow activity.
 
Action delete_this ()
 Terminates the flow and deletes *this.
 
Action set_terminated ()
 Sets the flow to terminated state.
 
Action call_immediately (Callback c)
 Imediately call the next state upon return.
 
Action wait ()
 Wait for an asynchronous call.
 
Action wait_and_call (Callback c)
 Wait for resource to become available before proceeding to next state.
 
template<class T >
Action allocate_and_call (FlowInterface< Buffer< T > > *target_flow, Callback c, Pool *pool=nullptr)
 Allocates a buffer from a pool and proceed to the next state when allocation is successful.
 
Action allocate_and_call (Callback c, QAsync *queue)
 Allocates an entry from an asynchronous queue, and transitions to a state once the allocation is complete.
 
template<class T >
Buffer< T > * full_allocation_result (FlowInterface< Buffer< T > > *target_flow)
 Takes the result of the asynchronous allocation without resetting the object.
 
template<class T >
T * full_allocation_result (TypedQAsync< T > *queue)
 Takes the result of the asynchronous allocation without resetting the object.
 
template<class T >
void cast_allocation_result (T **member)
 Takes the result of the asynchronous allocation without resetting the object.
 
template<class T >
Buffer< T > * get_allocation_result (FlowInterface< Buffer< T > > *target_flow)
 Takes the result of the asynchronous allocation.
 
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 CPU again.
 
Action yield ()
 Place the current flow to the back of the executor, and re-try the current state after we get the CPU again.
 
Action sleep_and_call (::Timer *timer, long long timeout_nsec, Callback c)
 Suspends execution of this control flow for a specified time.
 
template<class T , typename... Args>
Action invoke_subflow_and_wait (FlowInterface< Buffer< T > > *target_flow, Callback c, Args &&... args)
 Calls a helper flow to perform some actions.
 
Action read_repeated (StateFlowSelectHelper *helper, int fd, void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Blocks until size bytes are read and then invokes the next state.
 
Action read_single (StateFlowSelectHelper *helper, int fd, void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Attempts to read at most size_t bytes, and blocks the caller until at least one byte is read.
 
Action read_nonblocking (StateFlowSelectHelper *helper, int fd, void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Attempts to read at most size bytes, and then invokes the next state, even if only zero bytes are available right now.
 
Action read_repeated_with_timeout (StateFlowTimedSelectHelper *helper, long long timeout_nsec, int fd, void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Blocks until size bytes are read, or a timeout expires.
 
Action internal_try_read ()
 Implementation state that gets repeatedly called upon every wakeup and tries to make progress on reading.
 
Action write_repeated (StateFlowSelectHelper *helper, int fd, const void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Writes some data into a file descriptor, repeating the operation as necessary until all bytes are written.
 
Action internal_try_write ()
 Implementation state that gets repeatedly called upon every wakeup and tries to make progress on writing.
 
- Protected Member Functions inherited from QMember
 QMember ()
 Constructor.
 
 ~QMember ()
 Destructor.
 

Private Member Functions

Action terminated ()
 Terminates the current StateFlow activity.
 
void alloc_result (QMember *b) override
 Callback from a Pool in case of an asynchronous allocation.
 
 StateFlowBase ()
 Default constructor.
 
 DISALLOW_COPY_AND_ASSIGN (StateFlowBase)
 

Private Attributes

Serviceservice_
 Service this StateFlow belongs to.
 
Callback state_
 current active state in the flow
 
QMemberallocationResult_
 The result of the next allocation that comes in.
 

Additional Inherited Members

- Protected Attributes inherited from QMember
QMembernext
 pointer to the next member in the queue
 

Detailed Description

Base class for state machines.

A state machine is a form of collaborative multi-tasking. StateFlows can be scheduled on an executor, and alternately perform synchronous code (executing a state handler function) and an asynchronous operation (waiting for some event to happen). The asynchronous operations may include waiting for a message to arrive in a queue, or waiting for the allocation of an empty buffer, or a notification from a called lower-level library that a specific request has completed processing.

The current state of the StateFlow is represented by a function pointer the points to a member function of the current object. When the state flow is scheduled on an executor, it will execute the current state function. Upon the return of that state function some Action will be performed. The Actions to perform are represented by functions on the StateFlowBase class that return an Action structure, such as allocate_and_call(), wait_and_call(), or call_immediately(). Most factory functions that create these Actions will receive the new state handler as an argument; when the asynchronous action is complete, the state flow will resume execution in the presented state handler function.

Definition at line 170 of file StateFlow.hxx.

Member Typedef Documentation

◆ Callback

typedef Action(StateFlowBase::* StateFlowBase::Callback) ()
protected

State Flow callback prototype.

Definition at line 218 of file StateFlow.hxx.

Constructor & Destructor Documentation

◆ StateFlowBase()

StateFlowBase::StateFlowBase ( Service service)
inlineprotected

Constructor.

Parameters
serviceService that this state flow is part of

Definition at line 200 of file StateFlow.hxx.

◆ ~StateFlowBase()

StateFlowBase::~StateFlowBase ( )
inlineprotected

Destructor.

Definition at line 209 of file StateFlow.hxx.

Member Function Documentation

◆ again()

Action StateFlowBase::again ( )
inlineprotected

Call the current state again via call_immediately.

Returns
function pointer to current state handler

Definition at line 280 of file StateFlow.hxx.

◆ alloc_result()

void StateFlowBase::alloc_result ( QMember b)
inlineoverrideprivatevirtual

Callback from a Pool in case of an asynchronous allocation.

Parameters
bthe newly allocated payload object.

Reimplemented from Executable.

Definition at line 945 of file StateFlow.hxx.

◆ allocate_and_call() [1/2]

Action StateFlowBase::allocate_and_call ( Callback  c,
QAsync queue 
)
inlineprotected

Allocates an entry from an asynchronous queue, and transitions to a state once the allocation is complete.

Parameters
cis the state to transition to after allocation
queueis the queue to allocate from.
Returns
new state object to return from state function.

Definition at line 372 of file StateFlow.hxx.

◆ allocate_and_call() [2/2]

template<class T >
Action StateFlowBase::allocate_and_call ( FlowInterface< Buffer< T > > *  target_flow,
Callback  c,
Pool pool = nullptr 
)
inlineprotected

Allocates a buffer from a pool and proceed to the next state when allocation is successful.

Parameters
target_flowdefines the type of buffer to allocate.
cCallback "state" to move to after allocation
poolpool to allocate from; defaults to the pool of the target flow.
Returns
function pointer to be returned from state function

Definition at line 351 of file StateFlow.hxx.

◆ call_immediately()

Action StateFlowBase::call_immediately ( Callback  c)
inlineprotected

Imediately call the next state upon return.

Parameters
cCallback "state" to move to
Returns
function pointer to be returned from state function

Definition at line 318 of file StateFlow.hxx.

◆ cast_allocation_result()

template<class T >
void StateFlowBase::cast_allocation_result ( T **  member)
inlineprotected

Takes the result of the asynchronous allocation without resetting the object.

This should be the first statement in the state where the allocation transitioned. T must be descendant of QMember.

Parameters
memberwill be filled with the current / latest allocation result correctly casted to the given type.

Definition at line 411 of file StateFlow.hxx.

◆ delete_this()

Action StateFlowBase::delete_this ( )
inlineprotected

Terminates the flow and deletes *this.

Do not access any member function after this call has been made.

Returns
state object to return from state handle.

Definition at line 298 of file StateFlow.hxx.

◆ exit()

Action StateFlowBase::exit ( )
inlineprotected

Terminate current StateFlow activity.

The message instance is not released before termination. This is usefull if the message will be reused for the purpose of sending to another StateFlow.

Returns
function pointer to terminated method

Definition at line 290 of file StateFlow.hxx.

◆ full_allocation_result() [1/2]

template<class T >
Buffer< T > * StateFlowBase::full_allocation_result ( FlowInterface< Buffer< T > > *  target_flow)
inlineprotected

Takes the result of the asynchronous allocation without resetting the object.

This should be the first statement in the state where the allocation transitioned. If you expect an empty object, use get_allocation_result() instead.

Parameters
target_flowis the StateFlow for which we allocated.
Returns
The full buffer as it was inserted into the async queue.

Definition at line 386 of file StateFlow.hxx.

◆ full_allocation_result() [2/2]

template<class T >
T * StateFlowBase::full_allocation_result ( TypedQAsync< T > *  queue)
inlineprotected

Takes the result of the asynchronous allocation without resetting the object.

This should be the first statement in the state where the allocation transitioned. If you expect an empty object, use get_allocation_result() instead.

Parameters
queueis the typed queue which we allocated from.
Returns
The object that the queue gave to us.

Definition at line 399 of file StateFlow.hxx.

◆ get_allocation_result()

template<class T >
Buffer< T > * StateFlowBase::get_allocation_result ( FlowInterface< Buffer< T > > *  target_flow)
inlineprotected

Takes the result of the asynchronous allocation.

This should be the first statement in the state where the allocation transitioned.

Parameters
target_flowis the StateFlow for which we allocated.
Returns
an initialized buffer of the correct type.

Definition at line 1221 of file StateFlow.hxx.

◆ internal_try_read()

Action StateFlowBase::internal_try_read ( )
inlineprotected

Implementation state that gets repeatedly called upon every wakeup and tries to make progress on reading.

Returns
next action.

Definition at line 667 of file StateFlow.hxx.

◆ internal_try_write()

Action StateFlowBase::internal_try_write ( )
inlineprotected

Implementation state that gets repeatedly called upon every wakeup and tries to make progress on writing.

Returns
next action.

Definition at line 808 of file StateFlow.hxx.

◆ invoke_subflow_and_ignore_result()

template<class T , typename... Args>
static void StateFlowBase::invoke_subflow_and_ignore_result ( FlowInterface< Buffer< T > > *  target_flow,
Args &&...  args 
)
inlinestatic

Calls a helper flow to perform some actions.

Performs inline synchronous allocation form the main buffer pool. Ignores the target flow's buffer pool settings, because that makes it impossible to guarantee successful allocation.

Fills in the payload's arguments using the passed-in args by calling T::reset(args...). Then sends the buffer to the target flow, and ignores any response value.

Parameters
target_flowis a pointer to the helper flow to be used
argsare forwarded to the reset() method on the target flow's buffer type.

Definition at line 548 of file StateFlow.hxx.

◆ invoke_subflow_and_wait()

template<class T , typename... Args>
Action StateFlowBase::invoke_subflow_and_wait ( FlowInterface< Buffer< T > > *  target_flow,
Callback  c,
Args &&...  args 
)
inlineprotected

Calls a helper flow to perform some actions.

Performs inline synchronous allocation form the main buffer pool. Ignores the target flow's buffer pool settings, because that makes it impossible to guarantee successful allocation.

Fills in the payload's arguments using the passed-in args by calling T::reset(args...). Then sends the buffer to the target flow, and waits for the target flow to call return_buffer().

There are requirements on the arguments structure T:

struct Foo { void reset(...); BarrierNotifiable done; }

Parameters
target_flowis a pointer to the helper flow to be used
cis the next state after the target flow is completed
argsare forwarded to the reset() method on the target flow's buffer type.

Definition at line 521 of file StateFlow.hxx.

◆ is_state()

bool StateFlowBase::is_state ( Callback  c)
inlineprotected
Returns
true if the state flow is in a specific state.

Definition at line 253 of file StateFlow.hxx.

◆ is_terminated()

bool StateFlowBase::is_terminated ( )
inlineprotected
Returns
true if the current flow is terminated.

Definition at line 259 of file StateFlow.hxx.

◆ notify()

void StateFlowBase::notify ( )
overridevirtual

Wakeup call arrived.

Schedules *this on the executor. Does not know the priority.

Reimplemented from Executable.

Reimplemented in StateFlowWithQueue.

Definition at line 97 of file StateFlow.cxx.

◆ read_nonblocking()

Action StateFlowBase::read_nonblocking ( StateFlowSelectHelper helper,
int  fd,
void *  buf,
size_t  size,
Callback  c,
unsigned  priority = Selectable::MAX_PRIO 
)
inlineprotected

Attempts to read at most size bytes, and then invokes the next state, even if only zero bytes are available right now.

Parameters
helperstores intermediate state.
fdisthe file to read from
bufwhere to write data we've read
sizehow many bytes to read
cnext state to call after write is complete
pioritywhat execution priority we should be scheduling the intermediate and next states after the read is complete.

Definition at line 619 of file StateFlow.hxx.

◆ read_repeated()

Action StateFlowBase::read_repeated ( StateFlowSelectHelper helper,
int  fd,
void *  buf,
size_t  size,
Callback  c,
unsigned  priority = Selectable::MAX_PRIO 
)
inlineprotected

Blocks until size bytes are read and then invokes the next state.

Parameters
helperstores intermediate state.
fdisthe file to read from
bufwhere to write data we've read
sizehow many bytes to read
cnext state to call after write is complete
pioritywhat execution priority we should be scheduling the intermediate and next states after the read is complete.

Definition at line 570 of file StateFlow.hxx.

◆ read_repeated_with_timeout()

Action StateFlowBase::read_repeated_with_timeout ( StateFlowTimedSelectHelper helper,
long long  timeout_nsec,
int  fd,
void *  buf,
size_t  size,
Callback  c,
unsigned  priority = Selectable::MAX_PRIO 
)
inlineprotected

Blocks until size bytes are read, or a timeout expires.

If the timeout expires, jumps to next state with whatever data has been read. To figure out whether the timer expired or the read completed, the caller can check helper->remaining_ != 0.

Parameters
helperstores intermediate state.
timeout_nsecstop waiting for more data after this many nanoseconds elapsed
fdisthe file to read from
bufwhere to write data we've read
sizehow many bytes to read maximum
cnext state to call after write is complete
pioritywhat execution priority we should be scheduling the intermediate and next states after the read is complete.

Definition at line 646 of file StateFlow.hxx.

◆ read_single()

Action StateFlowBase::read_single ( StateFlowSelectHelper helper,
int  fd,
void *  buf,
size_t  size,
Callback  c,
unsigned  priority = Selectable::MAX_PRIO 
)
inlineprotected

Attempts to read at most size_t bytes, and blocks the caller until at least one byte is read.

Then the next state is invoked with whatever the first read returned.

Parameters
helperstores intermediate state.
fdisthe file to read from
bufwhere to write data we've read
sizehow many bytes to read maximum
cnext state to call after write is complete
pioritywhat execution priority we should be scheduling the intermediate and next states after the read is complete.

Definition at line 594 of file StateFlow.hxx.

◆ reset_flow()

void StateFlowBase::reset_flow ( Callback  c)
inlineprotected

Resets the flow to the specified state.

Parameters
cis the state to continue the flow from after the next notification.

Definition at line 247 of file StateFlow.hxx.

◆ run()

void StateFlowBase::run ( )
overridevirtual

Callback from the executor.

Executes the current state (until we get a wait or yield return).

This function will be invoked when the current stateflow gets the CPU. It will execute the current states until the flow yields or is blocked in a waiting state.

Implements Executable.

Definition at line 58 of file StateFlow.cxx.

◆ service()

Service * StateFlowBase::service ( )
inline

Return a pointer to the service I am bound to.

Returns
pointer to service

Definition at line 191 of file StateFlow.hxx.

◆ set_terminated()

Action StateFlowBase::set_terminated ( )
inlineprotected

Sets the flow to terminated state.

Returns
action to return from state handler.

Definition at line 309 of file StateFlow.hxx.

◆ sleep_and_call()

Action StateFlowBase::sleep_and_call ( ::Timer timer,
long long  timeout_nsec,
Callback  c 
)
inlineprotected

Suspends execution of this control flow for a specified time.

After the timeout expires the flow will continue in state c.

Parameters
timeris the timer to start. This timer should be set up to eventually call notify() on *this. We recommend using a StateFlowTimer.
timeout_nsecis the timeout with which to start the timer.
cis the next state to transition to when the timeout expires or the timer gets triggered.
Returns
state flow action.

Definition at line 493 of file StateFlow.hxx.

◆ start_flow()

void StateFlowBase::start_flow ( Callback  c)
inlineprotected

Resets the flow to the specified state and starts it.

Parameters
cis the state to start the flow from.

Definition at line 267 of file StateFlow.hxx.

◆ terminated()

StateFlowBase::Action StateFlowBase::terminated ( )
private

Terminates the current StateFlow activity.

This is a sink state, and there has to be an external call to do anything useful after this state has been reached.

Returns
delay.

Definition at line 126 of file StateFlow.cxx.

◆ wait()

Action StateFlowBase::wait ( )
inlineprotected

Wait for an asynchronous call.

Returns
special function pointer to return from a state handler that will cause the StateFlow to wait for an incoming wakeup (notification).

Definition at line 327 of file StateFlow.hxx.

◆ wait_and_call()

Action StateFlowBase::wait_and_call ( Callback  c)
inlineprotected

Wait for resource to become available before proceeding to next state.

Parameters
cState to move to
Returns
function pointer to be returned from state function

Definition at line 336 of file StateFlow.hxx.

◆ write_repeated()

Action StateFlowBase::write_repeated ( StateFlowSelectHelper helper,
int  fd,
const void *  buf,
size_t  size,
Callback  c,
unsigned  priority = Selectable::MAX_PRIO 
)
inlineprotected

Writes some data into a file descriptor, repeating the operation as necessary until all bytes are written.

Parameters
helpertemporary storage (usually local to the calling flow)
fdfiledes to write into
bufPointer to data to write. The data must stay alive until the next state is called.
sizeNumber of bytes of data to write.
cnext state function to call. Use the syntax STATE(my_state_fn)
priorityWhich priority to schedule the flow's next state when the write is complete.
Returns
action to return.

Definition at line 790 of file StateFlow.hxx.

◆ yield()

Action StateFlowBase::yield ( )
inlineprotected

Place the current flow to the back of the executor, and re-try the current state after we get the CPU again.

Similar to again, except we place this flow on the back of the Executor queue.

Returns
function pointer to be returned from state function

Definition at line 442 of file StateFlow.hxx.

◆ yield_and_call()

Action StateFlowBase::yield_and_call ( Callback  c)
inlineprotected

Place the current flow to the back of the executor, and transition to a new state after we get the CPU again.

Similar to call_immediately, except we place this flow on the back of the Executor queue.

Parameters
cCallback "state" to move to
Returns
function pointer to be returned from state function

Definition at line 430 of file StateFlow.hxx.

Member Data Documentation

◆ allocationResult_

QMember* StateFlowBase::allocationResult_
private

The result of the next allocation that comes in.

Definition at line 955 of file StateFlow.hxx.

◆ service_

Service* StateFlowBase::service_
private

Service this StateFlow belongs to.

Definition at line 934 of file StateFlow.hxx.

◆ state_

Callback StateFlowBase::state_
private

current active state in the flow

Definition at line 952 of file StateFlow.hxx.


The documentation for this class was generated from the following files: