5. OnPollPreparePfn和OnPollProcessEvent回调函数
libco的poll函数可以用于事件的注册,包括文件事件和时间事件。文件事件指的是网络套接字是否可读或者可写,而时间事件则相当于是一个定时器,在定时器指定的时间超时后继续执行。在hello word的例子中,生产者协程就调用poll注册了一个时间事件。
void* Producer(void* args)
{
co_enable_hook_sys();
stEnv_t* env= (stEnv_t*)args;
int id = 0;
while (true)
{
stTask_t* task = (stTask_t*)calloc(1, sizeof(stTask_t));
task->id = id++;
env->task_queue.push(task);
printf("%s:%d produce task %d\n", __func__, __LINE__, task->id);
co_cond_signal(env->cond);
poll(NULL, 0, 1000); // 注册时间事件,相当于sleep 1s
}
return NULL;
}
1. 注册事件poll
poll这个函数的3个函数参数和系统调用API里面的I/O多路复用函数poll完全一样,这里会根据是否使能hook来调用poll函数还是使用epoll_ctl()。
int poll(struct pollfd fds[], nfds_t nfds, int timeout)
{
HOOK_SYS_FUNC( poll );
if( !co_is_enable_sys_hook() ) // 如果没有使能hook,那么直接调用原生的API poll
{
return g_sys_poll_func( fds,nfds,timeout );
}
return co_poll_inner(co_get_epoll_ct(), fds, nfds, timeout, g_sys_poll_func);
}
如果fds传入NULL,nfds传入为0,那么这个函数则就是一个定时器函数,将会在timeout时间之后继续执行。
2. 相关数据结构
typedef void (*OnPreparePfn_t)( stTimeoutItem_t *,struct epoll_event &ev, stTimeoutItemLink_t *active );
typedef void (*OnProcessPfn_t)( stTimeoutItem_t *);
struct stTimeoutItem_t
{
enum
{
eMaxTimeout = 40 * 1000 // 最大超时为40s
};
stTimeoutItem_t *pPrev;
stTimeoutItem_t *pNext;
stTimeoutItemLink_t *pLink;
unsigned long long ullExpireTime;
OnPreparePfn_t pfnPrepare;
OnProcessPfn_t pfnProcess;
void *pArg; // 指向协程的结构体指针
bool bTimeout;
};
struct stPo