/* State machine control block - one per running instance of a state
* machine
*/
typedef struct PINT_smcb
{
/* state machine execution variables */
int stackptr;
struct PINT_state_s *current_state;
struct PINT_state_stack_s state_stack[PINT_STATE_STACK_SIZE];
struct qlist_head frames; /* circular list of frames */
int base_frame; /* index of current base frame */
int frame_count; /* number of frames in list */
/* usage specific routinet to look up SM from OP */
struct PINT_state_machine_s *(*op_get_state_machine)(int);
/* state machine context and control variables */
int op; /* this field externally indicates type of state machine */
PVFS_id_gen_t op_id; /* unique ID for this operation */
struct PINT_smcb *parent_smcb; /* points to parent smcb or NULL */
int op_terminate; /* indicates SM is ready to terminate */
int op_cancelled; /* indicates SM operation was cancelled */
int children_running; /* the number of child SMs running */
int op_completed; /* indicates SM operation was added to completion Q */
/* add a lock here */
job_context_id context; /* job context when waiting for children */
int (*terminate_fn)(struct PINT_smcb *, job_status_s *);
void *user_ptr; /* external user pointer */
int immediate; /* specifies immediate completion of the state machine */
} PINT_smcb;
#define PINT_SET_OP_COMPLETE do{PINT_smcb_set_complete(smcb);} while (0)
struct PINT_state_machine_s
{
const char *name;
struct PINT_state_s *first_state;
};
struct PINT_state_s
{
const char *state_name;
struct PINT_state_machine_s *parent_machine;
enum PINT_state_code flag;
union
{
int (*func)(struct PINT_smcb *, job_status_s *);
struct PINT_state_machine_s *nested;
} action;
struct PINT_pjmp_tbl_s *pjtbl;
struct PINT_tran_tbl_s *trtbl;
};
struct PINT_pjmp_tbl_s
{
int return_value;
enum PINT_state_code flag;
struct PINT_state_machine_s *state_machine;
};
struct PINT_tran_tbl_s
{
int return_value;
enum PINT_state_code flag;
struct PINT_state_s *next_state;
};