quagga是开源路由器软件,提供的用户界面与思科,华为的路由器的人机接口几乎一致,非常有学习价值,尤其是开源的协议代码,简直亮瞎了我的小眼睛。
quagga的介绍,我就不赘述了,有兴趣的可以找度娘或者去官网看看。
一、通用库thread
quagga是一个纯C实现的项目。
C语言的项目,就是一个个C,H文件组成,当C文件很多的时候,相信一开始每个开源爱好者都会感到很头疼吧,完全不知道这么多文件要怎么组织,怎么去阅读吧?
哈,其实呢,quagga的C文件就像一个个散落在地上的珍珠,而thread这个库就像织女手中的金丝线,把这些闪闪发光的珍珠完美的串连起来,就会发出璀璨夺目的光彩。
嗯,在quagga每个实现的协议的main函数里都会有如下类似的代码:
/* Start finite state machine, here we go! */
while (thread_fetch (bm->master, &thread))
thread_call (&thread);
看到上面的注释了吗?嗯,没错,这是这个有限状态机,但是程序猿们的直觉,过期的注释都是不可靠,是的,这是个在有限状态里,无限循环的状态机。。
哦,要补充说明一下thread,这个不同于pthread,它的声明如下:
/* Thread itself. */
struct thread
{
thread_type type; /* thread type */
thread_type add_type; /* thread type */
struct thread *next; /* next pointer of the thread */
struct thread *prev; /* previous pointer of the thread */
struct thread_master *master; /* pointer to the struct thread_master. */
int (*func) (struct thread *); /* event function */
void *arg; /* event argument */
union {
int val; /* second argument of the event. */
int fd; /* file descriptor in case of read/write. */
struct timeval sands; /* rest of time sands value. */
} u;
int index; /* used for timers to store position in queue */
struct timeval real;
struct cpu_thread_history *hist; /* cache pointer to cpu_history */
const char *funcname;
const char *schedfrom;
int schedfrom_line;
};
它其实是描述了一个要在指定消息来临时要执行的任务,并且提供了任务调度时需要判断的时间片段。
下面就是一个协议代码main函数中常见事件添加:
switch (event)
{
case ZCLIENT_SCHEDULE:
if (! zclient->t_connect)
zclient->t_connect =
thread_add_event (zclient->master, zclient_connect, zclient, );
break;
如此,thread_master就会源源不断的搞出一些跟各个c文件都相关的事情来,然后通过thread_fetch的调度,然后thread_call中执行相应的任务。
1 (*thread->func)(thread);
执行完具体任务后,回到thread_fetch开始下一个thread。