libevent源码分析--epoll_dispatch()

这个函数是相当于在event_dispatch()中调用的那个函数的真实面目,传递给这个函数的参数中有event_base,还有一个arg买这个arg在这里就是struct  epollop.还有一个时间值。

static int
192 epoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
193 {
194     struct epollop *epollop = arg;
195     struct epoll_event *events = epollop->events;
196     struct evepoll *evep;
197     int i, res, timeout = -1;
198 
199     if (tv != NULL)
200         timeout = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
201 
202     if (timeout > MAX_EPOLL_TIMEOUT_MSEC) {
203         /* Linux kernels can wait forever if the timeout is too big;
204          * see comment on MAX_EPOLL_TIMEOUT_MSEC. */
205         timeout = MAX_EPOLL_TIMEOUT_MSEC;
206     }
207 
208     res = epoll_wait(epollop->epfd, events, epollop->nevents, timeout);
209 
210     if (res == -1) {
211         if (errno != EINTR) {
212             event_warn("epoll_wait");
213             return (-1);
214         }
215 
216         evsignal_process(base);
217         return (0);
218     } else if (base->sig.evsignal_caught) {
219         evsignal_process(base);
220     }
221 
222     event_debug(("%s: epoll_wait reports %d", __func__, res));
223 
224     for (i = 0; i < res; i++) {
225         int what = events[i].events;
226         struct event *evread = NULL, *evwrite = NULL;
227         int fd = events[i].data.fd;
228 
229         if (fd < 0 || fd >= epollop->nfds)
230             continue;
231         evep = &epollop->fds[fd];
232 
233         if (what & (EPOLLHUP|EPOLLERR)) {
234             evread = evep->evread;
235             evwrite = evep->evwrite;
236         } else {
 237      if (what & EPOLLIN) {
238                 evread = evep->evread;
239             }
240 
241             if (what & EPOLLOUT) {
242                 evwrite = evep->evwrite;
243             }
244         }
245 
246         if (!(evread||evwrite))
247             continue;
248 
249         if (evread != NULL)
250             event_active(evread, EV_READ, 1);
251         if (evwrite != NULL)
252             event_active(evwrite, EV_WRITE, 1);
253     }
254 
255     return (0);
256 }

在200行左右首先是决定阻塞的事件,,208是轮询。不过这里看代码需要知道一定的epoll_wait的知识,在我的博客中有很多与之相关的介绍。

epoll_wait返回的结果就是有多少个套接字可以使用,224行开始的for循环就是处理这些套接字。注意这里并没有事件处理的业务,这些业务都是在event_base_loop中,调用的是event_process_active。

到目前为止,libevent库上关于网络编程的主*分都已经结束,不过还有很多别的内容,这里省略了关于信号的所有东西,还有一个很关键的部分就是buffer相关内容。还有这个库中一个内嵌的http服务器。当然这些也很重要,不过讲解的安排不在这里。这些内容等日后再聊。

这也是我第一次比较详细、系统的去分析一个东西(当然相比CSDN上的前辈,我仍旧是nobody)自己的理解自己写出来会有一个更好的理解。这样也会督促自己更加深入,考试结束后的安心一天把本该属于2013年终结的事件做个了断,也算是给2014年开一个好头!!!共同学习!加油!还有很多事件要做,还有很多东西要学,还有很多书要看!!!

libevent源码分析--epoll_dispatch()

上一篇:(转)笔记320 SQLSERVER中的加密函数 2013-7-11


下一篇:转载——2秒内向数据库中插入十万条数据?