Chinaunix首页 | 论坛 | 博客
  • 博客访问: 492584
  • 博文数量: 78
  • 博客积分: 995
  • 博客等级: 准尉
  • 技术积分: 1462
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-15 20:22
个人简介

技术中沉思的时候最快乐,问题得到完美解决的时候最有成就感!

文章分类

全部博文(78)

文章存档

2013年(39)

2012年(37)

2011年(2)

分类: LINUX

2013-09-16 17:15:18

    接手他人代码,单进程单线程异步复用,用的裸接口,发现线上有个bug,之前用的边缘触发,改成水平触发后,问题不断;
今天发现,有时write evt事件在某些条件下,一直得不到调用,反而一直在调用 read evt 的callback,导致死循环;
    lsof 发现,这个进程对应的某些fd已经完全被系统回收了(即已经显示不了tcp两对ip+port了)
    问题清晰的表明:write evt 是生效的,但为什么一直调用read的callback呢?read evt 实际都已经关掉了;
    于是查代码,最后,发现上层epoll_wait 之后的event处理流程问题:
  1.         bool hasErr = false;
  2.         if ((events[i].events & EPOLLIN)
  3.             || (events[i].events & EPOLLHUP)
  4.             || (events[i].events & EPOLLERR))
  5.         {
  6.             if (sess->onRead(eed->side) != 0)
  7.             {
  8.                 hasErr = true;...
  9.             }
  10.         }
  11.         //处理可写事件
  12.         if ((events[i].events & EPOLLOUT) && (!hasErr))
  13.         {
  14.             if (sess->onWrite(eed->side) != 0)
  15.             {
  16.                 hasErr = true;...
  17.             }
  18.         }

    看到这里,一下就明白了:某些条件下,fd被另外一端直接关闭了,此时虽然注册的是 EPOLLOUT,但返回的event实际为 EPOLLHUP,
很简单的就修正了,之前花了很多时间在查callback函数本身的实现和逻辑;结果是上层事件处理问题;    
    
    呃,一堆相似的问题,加上之前的循环buf的bug,还有read,write返回和errorno等等问题,处理了一次又一次;重复的临时的造轮子,
确实太容易出问题了;把这些都封装好,就不要去碰了,要不肯定还会一次又一次写出相似的代码,但总会这里有问题那里有bug;

    蛋疼的很,这些问题其实碰到过n次了


    btw,最后在网上顺便查了下 EPOLLHUP 事件:

    当socket的一端认为对方发来了一个不存在的4元组请求的时候,会回复一个RST响应,在epoll上会响应为EPOLLHUP事件,目前我已知的两种情况会发响应RST

    [1] 当客户端向一个没有在listen的服务器端口发送的connect的时候 服务器会返回一个RST 因为服务器根本不知道这个4元组的存在
    [2] 当已经建立好连接的一对客户端和服务器,客户端突然操作系统崩溃,或者拔掉电源导致操作系统重新启动(kill pid或者正常关机不行的,因为操作系统会发送FIN给对方).
         这时服务器在原有的4元组上发送数据,会收到客户端返回的RST,因为客户端根本不知道之前这个4元组的存在
阅读(6407) | 评论(0) | 转发(0) |
0

上一篇:awk 条件输出

下一篇:python utils

给主人留下些什么吧!~~