在Libev中,使用poll作为backend时,涉及到下面几种数据结构:

int *pollidxs;
int pollidxmax; struct pollfd *polls;
int pollmax;
int pollcnt;

polls就是struct pollfd结构的数组,pollmax是该数组的实际大小,pollcnt表示该数组中,有效结构的个数。也就是监控的描述符个数。

pollidxs是整型数组,以描述符fd为下标,pollidxs[fd]表示该fd对应的struct pollfd结构在polls中的下标。pollidxs[fd]== -1表示该描述符无效。pollidxmax表示pollidxs数组的大小。

增加pollidxs这种结构,主要是为了在取消监控fd时,能够快速定位polls,从而加快取消速度。

因此,上面的结构满足等式:

idx = pollidxs [fd];
polls[idx].fd == fd;

1:poll_init

以poll为backend时,相关的函数和数据结构初始化。代码如下:

backend_mintime = 1e-3;
backend_modify = poll_modify;
backend_poll = poll_poll; pollidxs = 0; pollidxmax = 0;
polls = 0; pollmax = 0; pollcnt = 0;

2:poll_modify

主要设置相关fd的struct pollfd结构,完整代码如下:

static void poll_modify (struct ev_loop *loop, int fd, int oev, int nev)
{
int idx; if (oev == nev)
return;
array_needsize (int, pollidxs, pollidxmax, fd + 1, pollidx_init); idx = pollidxs [fd]; if (idx < 0) /* need to allocate a new pollfd */
{
pollidxs [fd] = idx = pollcnt++;
array_needsize (struct pollfd, polls, pollmax, pollcnt, EMPTY2);
polls [idx].fd = fd;
} assert (polls [idx].fd == fd); if (nev)
polls [idx].events = (nev & EV_READ ? POLLIN : 0) | (nev & EV_WRITE ? POLLOUT : 0);
else /* remove pollfd */
{
pollidxs [fd] = -1;
if (expect_true (idx < --pollcnt))
{
polls [idx] = polls [pollcnt];
pollidxs [polls [idx].fd] = idx;
}
}
}

代码还是比较好理解的,首先取得pollidxs [fd]的值,也就是该fd对应的struct pollfd结构在polls数组中的下标。如果该值为-1,说明该fd是第一次加入监控,相应的设置pollidxs[fd]和polls [idx]。

如果env不为0,则设置struct pollfd结构中的events,如果它为0,表示要去除该fd的监控,首先置pollidxs [fd] = -1表示该fd无效,然后去除相应的struct pollfd结构,首先--pollcnt,如果idx == pollcnt,则直接退出即可,否则,将polls数组中的最后一个元素置换到polls[idx]中,并设置相应的pollidxs元素。

3:poll_poll

主要调用poll函数,等待描述符事件的触发。主要是对触发的描述符和事件调用fd_event。主要代码如下:

res = poll (polls, pollcnt, timeout * 1e3);
if (expect_false (res < 0))
{
...
}
else
for (p = polls; res; ++p)
{
assert (("libev: poll() returned illegal result, broken BSD kernel?", p < polls + pollcnt)); if (expect_false (p->revents)) /* this expect is debatable */
{
--res;
if (expect_false (p->revents & POLLNVAL))
fd_kill (EV_A_ p->fd);
else
fd_event (EV_A_ p->fd, (p->revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
| (p->revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0));
}
}

最新文章

  1. 无脑简单 命令升级git Centos
  2. Django底层剖析之一次请求到响应的整个流程
  3. asp.net链接数据库问题,设置收藏本站,设置主页
  4. linux下命令运行目录上程序前面要加./
  5. Ubiquitous Religions 分类: POJ 2015-06-16 17:13 11人阅读 评论(0) 收藏
  6. 10个Laravel4开发者必用扩展包
  7. wcf使用ssl连接方式设置
  8. java 集合框架(三)Collection
  9. vs2012,打开早期版本窗体错误
  10. scala时间和时间戳互转
  11. ubuntu下makeinfo安装,其实真正安装的是texinfo包
  12. FTPService工具类
  13. RxSwift学习笔记7:buffer/window/map/flatMap/flatMapLatest/flatMapFirst/concatMap/scan/groupBy
  14. LPC18xx/43xx OTP Controller driver
  15. HDU 3546
  16. Servlet各版本web.xml的头文件配置模板
  17. LevelDB场景分析2--Open
  18. C# CultureInfo中常用的InvariantCulture
  19. jQuery中resetForm与clearForm的区别?
  20. 运行百度语音识别官方iOS demo报错: load offline engine failed: 4001

热门文章

  1. ubuntu 12.4,搞定apt源
  2. 学习线程池源码--ThreadPoolExecutor
  3. rabbitmq启用和禁用web界面管理插件
  4. django中模板
  5. PAI-STUDIO通过Tensorflow处理MaxCompute表数据
  6. 怎样判断一个exe可执行程序(dll文件)是32位的还是64位的
  7. javascript函数式编程和链式优化
  8. font-family:黑体;导致css定义全部不起作用
  9. 使用Centos7 安装docker的步骤
  10. 用Direct2D和DWM来做简单的动画效果2