免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1219 | 回复: 1
打印 上一主题 下一主题

[FastDFS] 发现一个可能导致异常的未定义行为 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-12 15:31 |只看该作者 |倒序浏览
版本5.02
在一个非阻塞的socket上读取8字节,并不能保证每次都读取到8字节,若由于系统繁忙没有读取到8字节,将导致异常。


1)线程间的通知采用pipe来产生两个socket  (storage_service.c 1639)
                if (pipe(pThreadData->thread_data.pipe_fds) != 0)
                {
                        result = errno != 0 ? errno : EPERM;
                        logError("file: "__FILE__", line: %d, " \
                                "call pipe fail, " \
                                "errno: %d, error info: %s", \
                                __LINE__, result, STRERROR(result));
                        break;
                }

2)将读socket设置成非阻塞,写socket还是阻塞的 (storage_service.c 1650)
                if ((result=fd_add_flags(pThreadData->thread_data.pipe_fds[0], \
                                O_NONBLOCK | O_NOATIME)) != 0)
                {
                        break;
                }
3)创建一个任务并将该任务的地址写入到 pipe_fds[1]  (storage_service.c 174
task_addr = (long)pTask;
write(pThreadData->thread_data.pipe_fds[1], &task_addr, sizeof(task_addr)) != sizeof(task_addr)

4) pipe_fds[0]读事件处理函数,他这里直接使用一个read读取8字节,因为是非阻塞并不能保证都会读到8个字节吧
如果没有读到8个字节那么这个task_addr就是异常的吧   (storage_nio.c 134)
        while (1)
        {
                if ((bytes=read(sock, &task_addr, sizeof(task_addr))) < 0)
                {
                        if (!(errno == EAGAIN || errno == EWOULDBLOCK))
                        {
                                logError("file: "__FILE__", line: %d, " \
                                        "call read failed, " \
                                        "errno: %d, error info: %s", \
                                        __LINE__, errno, STRERROR(errno));
                        }

                        break;
                }
                else if (bytes == 0)
                {
                        logError("file: "__FILE__", line: %d, " \
                                "call read failed, end of file", __LINE__);
                        break;
                }

                pTask = (struct fast_task_info *)task_addr;

论坛徽章:
4
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11IT运维版块每日发帖之星
日期:2016-08-11 06:20:00IT运维版块每日发帖之星
日期:2016-08-15 06:20:00
2 [报告]
发表于 2014-08-12 21:04 |只看该作者
从逻辑上,的确存在一次读不到8个字节的异常情况。
但是,take easy, OS会保证一次能读到8个字节。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP