状态机是事务处理中必不可少,在tsk_fsm.h/c里就实现了状态机机制,而且在各个协议层都会用到大量的状态机。只有学好了状态机,才能真正了解Doubango的运行机制,才能对Doubango修改和定制。
要定义一个状态机,首先需要有状态(state),还有事件(action),还有对事件的处理(exec)。下面是状态机的结构:
typedef struct tsk_fsm_s
{
TSK_DECLARE_OBJECT;
unsigned debug:1;
tsk_fsm_state_id current;
tsk_fsm_state_id term;
tsk_fsm_entries_L_t* entries;
tsk_fsm_onterminated_f callback_term;
const void* callback_data;
TSK_DECLARE_SAFEOBJ;
}
tsk_fsm_t;
TSK_DECLARE_OBJECT学了前一批就知道是啥了,略过。current和term分别是起始状态和结束状态;callback_term是状态机结束时调用的清理函数;callback_data是状态机构造时保存的数据,待到状态机结束时用的;entries是个list,里面对应的是每个状态对每个事件的处理,结构体如下:
typedef struct tsk_fsm_entry_s
{
TSK_DECLARE_OBJECT;
tsk_fsm_state_id from;
tsk_fsm_action_id action;
tsk_fsm_cond cond;
tsk_fsm_state_id to;
tsk_fsm_exec exec;
const char* desc;
}
tsk_fsm_entry_t;
其中from是当前状态,action是输入的动作,cond是个返回boolean的函数,如果调用cond返回false,则说明当前action无效,状态机不做任何变化;如果是true则把状态切换到to,然后执行exec。可以阅读以下tsk_fsm_act函数,里面很简单就不贴上了。
总结一下FSM的用法:
1,调用tsk_fsm_create创建一个状态机,两个参数分别是起始状态(current)和结束状态(term)。
2,调用tsk_fsm_set_callback_terminated来设置callback_term和callback_data.
3,调用tsk_fsm_set来初始化fsm。这一步设置fsm_entrys,查看一下TSK_FSM_ADD宏还有调用的地方,看看如何使用的。
4, 至此状态机初始化完成,之后调用tsk_fsm_act来为fsm输入事件和数据。
5,其他还有一些辅助函数和宏,检查一下tsk_fsm.h吧。