Squid Epoll网络模型
来源:互联网 发布:单点登录系统源码 编辑:程序博客网 时间:2024/05/17 01:05
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。
0 0
- Squid Epoll网络模型
- 网络io模型:epoll
- Linux网络epoll模型
- Linux网络编程epoll模型
- Linux网络编程epoll模型
- 高并发EPOLL网络模型
- select和epoll网络模型
- Linux select/epoll网络模型
- linux的网络模型---epoll
- 简单高效epoll网络模型
- 【网络编程】Epoll模型讲解
- C++ - 网络编程模型 - Linux EPOLL
- C++ - 网络编程模型 - Linux EPOLL
- C++ - 网络编程模型 - Linux EPOLL
- C++ - 网络编程模型 - Linux EPOLL
- C++ - 网络编程模型 - Linux EPOLL .
- select、poll、epoll 网络模型比较
- C++ - 网络编程模型 - Linux EPOLL
- linux kafka 搭建运行环境
- .net连接sqlite数据库
- Xcode 报错: Extra argument in call
- 抽象工厂模式-Abstract Factory Pattern
- HDU 5078--Osu!【水题】
- Squid Epoll网络模型
- poj 1837 dp
- C++内联函数
- wireshark抓包图解 TCP三次握手/四次挥手详解
- Android通过Xutils注解实例化以及事件绑定
- Squares
- enum类型,定义、变量长度、与int转换、与string转换
- openwrt中基于L2TP的VPN测试
- win7下debug native 环境搭建