设为首页 收藏本站
查看: 1635|回复: 0

[经验分享] Squid Epoll网络模型

[复制链接]

尚未签到

发表于 2015-11-19 13:38:44 | 显示全部楼层 |阅读模式
Squid Epoll网络模型

Squid 历经2.x, 3.x,官网已经有正在开发中的4.0版本。
Squid如今以20万行风骚代码让码农们找不着北了,本文就以Squid-4.0.0的源码为例吐槽一下。
Squid编译时可以根据OS自动选择支持的网络模型,对网络的支持最终会编译到ModEpoll.cc、
ModKqueue.cc、ModPoll.cc、ModSelect.cc。这些文件针对不同网络都有实现,
最终导出几个公共函数SelectLoopInit、SetSelect、ResetSelect、DoSelect。

  风骚的SetSelect

SetSelect(int fd, unsigned int type, PF * handler, void *client_data, time_t timeout)
// If read is an interest
if (type & COMM_SELECT_READ) {
if (handler) {
// Hack to keep the events flowing if there is data immediately ready
if (F->flags.read_pending)
ev.events |= EPOLLOUT;
ev.events |= EPOLLIN;
}
F->read_handler = handler;
F->read_data = client_data;
// Otherwise, use previously stored value
} else if (F->epoll_state & EPOLLIN) {
ev.events |= EPOLLIN;
}
// If write is an interest
if (type & COMM_SELECT_WRITE) {
if (handler)
ev.events |= EPOLLOUT;
F->write_handler = handler;
F->write_data = client_data;
// Otherwise, use previously stored value
} else if (F->epoll_state & EPOLLOUT) {
ev.events |= EPOLLOUT;
}
if (ev.events)
ev.events |= EPOLLHUP | EPOLLERR;
if (ev.events != F->epoll_state) {
if (F->epoll_state) // already monitoring something.
epoll_ctl_type = ev.events ? EPOLL_CTL_MOD : EPOLL_CTL_DEL;
else
epoll_ctl_type = EPOLL_CTL_ADD;
F->epoll_state = ev.events;
根据SetSelect设置的读写类型Read或者Write保留其它事件不变,
从而达到每次只改变需要设置的事件回调。最终根据ev.events的值判断
是否需要Mod或者Del。

  吊的不行的DoSelect

        if (cevents->events & (EPOLLIN|EPOLLHUP|EPOLLERR) || F->flags.read_pending) {
if ((hdl = F->read_handler) != NULL) {
debugs(5, DEBUG_EPOLL ? 0 : 8, HERE << "Calling read handler on FD " << fd);
PROF_start(comm_write_handler);
F->flags.read_pending = 0;
F->read_handler = NULL;
hdl(fd, F->read_data);
PROF_stop(comm_write_handler);
++ statCounter.select_fds;
} else {
debugs(5, DEBUG_EPOLL ? 0 : 8, HERE << "no read handler for FD " << fd);
// remove interest since no handler exist for this event.
SetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
}
}
if (cevents->events & (EPOLLOUT|EPOLLHUP|EPOLLERR)) {
if ((hdl = F->write_handler) != NULL) {
debugs(5, DEBUG_EPOLL ? 0 : 8, HERE << "Calling write handler on FD " << fd);
PROF_start(comm_read_handler);
F->write_handler = NULL;
hdl(fd, F->write_data);
PROF_stop(comm_read_handler);
++ statCounter.select_fds;
} else {
debugs(5, DEBUG_EPOLL ? 0 : 8, HERE << "no write handler for FD " << fd);
// remove interest since no handler exist for this event.
SetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
}
}
每次执行完回调后handler = NULL,epoll在该套接字下一次事件中
SetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0)将该套接字删除,
所以如果还想继续监听套接字事件必需在回调函数中手动执行SetSelect。

  提取的Epoll模型
感受到Squid的如此强大,不由自主的提取了框架并做了一个小Demo。
顺便献上git地址https://github.com/strong46066999/epoll。

版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-141194-1-1.html 上篇帖子: Squid性能杀手——fwdFail分析 下篇帖子: Squid第六章 访问控制
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表