内容简介:wifidog源码分析Lighttpd1.4.20源码分析之fdevent系统(2)-----初始化(2)
所设置的值就是上面定义的那个数组中元素的第二个成员(字符串)的值。
如果配置文件中没有配置,那么就使用上面定义的数组的第一个元素的值。这也就是为什么定义的时候那个 排序 很有意思的原因。
如果配置文件中有配置,那就按配置文件的来喽。(上面的代码删除了处理出错的部分)
从congif_set_defaults()函数回来,继续在main函数中走。
下面的语句设置最大描述符数量:
if (srv->event_handler == FDEVENT_HANDLER_SELECT)
{
/*
* select的硬限制。减去200是为了增加安全性,防止出现段错误。
*/
srv->max_fds = FD_SETSIZE - 200;
}
else
{
srv->max_fds = 4096;
}
由于select()函数一次能处理的fd数量有限制,所以要特殊处理。FD_SETSIZT在select.h中定义。其他情况最大描述符数量都设置为4096.
后面还有一个设置最大fd数量的地方:
//根据实际设置情况,重新设置max_fds。
if (srv->event_handler == FDEVENT_HANDLER_SELECT)
{
srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ?
rlim.rlim_cur : FD_SETSIZE - 200;
}
else
{
srv->max_fds = rlim.rlim_cur;
}
这个是根据当前用户的限制来的。当程序产生子进程后,在子进程中执行的第一条语句就是初始化fdevent系统:
if (NULL == (srv->ev = fdevent_init(srv->max_fds + 1,
srv->event_handler)))
{
log_error_write(srv, __FILE__, __LINE__, "s",
"fdevent_init failed");
return -1;
}
进入fdevent_init()函数:
/**
* 初始化文件描述符事件数组fdevent
*/
fdevents *fdevent_init(size_t maxfds, fdevent_handler_t type)
{
fdevents *ev;
//内存被初始化为0
ev = calloc(1, sizeof(*ev));
//分配数组
ev->fdarray = calloc(maxfds, sizeof(*ev->fdarray));
ev->maxfds = maxfds;
//根据设定的多路IO的类型进行初始化。
switch (type)
{
case FDEVENT_HANDLER_POLL:
if (0 != fdevent_poll_init(ev))
{
fprintf(stderr, "%s.%d: event-handler poll failed\n", __FILE__, __LINE__);
return NULL;
}
break;
case FDEVENT_HANDLER_SELECT:
if (0 != fdevent_select_init(ev))
{
fprintf(stderr, "%s.%d: event-handler select failed\n", __FILE__, __LINE__);
return NULL;
}
break;
case FDEVENT_HANDLER_LINUX_RTSIG:
if (0 != fdevent_linux_rtsig_init(ev))
{
fprintf(stderr, "%s.%d: event-handler linux-rtsig failed, try to set server.event-handler = \"poll\" or \"select\"\n",
__FILE__, __LINE__);
return NULL;
}
break;
case FDEVENT_HANDLER_LINUX_SYSEPOLL:
if (0 != fdevent_linux_sysepoll_init(ev))
{
fprintf(stderr, "%s.%d: event-handler linux-sysepoll failed, try to set server.event-handler = \"poll\" or \"select\"\n",
__FILE__, __LINE__);
return NULL;
}
break;
case FDEVENT_HANDLER_SOLARIS_DEVPOLL:
if (0 != fdevent_solaris_devpoll_init(ev))
{
fprintf(stderr, "%s.%d: event-handler solaris-devpoll failed, try to set server.event-handler = \"poll\" or \"select\"\n",
__FILE__, __LINE__);
return NULL;
}
break;
case FDEVENT_HANDLER_FREEBSD_KQUEUE:
if (0 != fdevent_freebsd_kqueue_init(ev))
{
fprintf(stderr, "%s.%d: event-handler freebsd-kqueue failed, try to set server.event-handler = \"poll\" or \"select\"\n",
__FILE__, __LINE__);
return NULL;
}
break;
default:
fprintf(stderr, "%s.%d: event-handler is unknown, try to set server.event-handler = \"poll\" or \"select\"\n",
__FILE__, __LINE__);
return NULL;
}
return ev;
}
fdevent_init()函数根据fdevent_handler_t的值调用相应的初始化函数。我们前面已经假设系统使用epoll,那么进入
fdevent_linux_sysepoll_init()函数:
int fdevent_linux_sysepoll_init(fdevents * ev)
{
ev->type = FDEVENT_HANDLER_LINUX_SYSEPOLL;
#define SET(x) \
ev->x = fdevent_linux_sysepoll_##x;
SET(free);
SET(poll);
SET(event_del);
SET(event_add);
SET(event_next_fdndx);
SET(event_get_fd);
SET(event_get_revent);
//创建epoll
if (-1 == (ev->epoll_fd = epoll_create(ev->maxfds)))
{
fprintf(stderr, "%s.%d: epoll_create failed (%s), try
to set server.event-handler = \"poll\" or \"select\"\n",
__FILE__, __LINE__, strerror(errno));
return -1;
}
//设置epoll_fd为运行exec()函数时关闭。
if (-1 == fcntl(ev->epoll_fd, F_SETFD, FD_CLOEXEC))
{
fprintf(stderr, "%s.%d: epoll_create failed (%s), try
to set server.event-handler = \"poll\" or \"select\"\n",
__FILE__, __LINE__, strerror(errno));
close(ev->epoll_fd);
return -1;
}
//创建fd事件数组。在epoll_wait函数中使用。存储发生了IO事件的fd和
//对应的IO事件。
ev->epoll_events = malloc(ev->maxfds *
sizeof(*ev->epoll_events));
return 0;
}
函数中首先通过SET宏对fdevents结构体中的函数指针赋值。然后创建epoll,最后做一些设置。
至此fdevent的初始化工作已经全部完成了。
额,没想到初始化讲了这么多。还是等下一篇再讲使用吧。。。
本文章由 http://www.wifidog.pro/2015/04/20/wifidog%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90Lighttpd%E5%88%9D%E5%A7%8B%E5%8C%96-2.html 整理编辑,转载请注明出处
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 以太坊源码分析(36)ethdb源码分析
- [源码分析] kubelet源码分析(一)之 NewKubeletCommand
- libmodbus源码分析(3)从机(服务端)功能源码分析
- [源码分析] nfs-client-provisioner源码分析
- [源码分析] kubelet源码分析(三)之 Pod的创建
- Spring事务源码分析专题(一)JdbcTemplate使用及源码分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
妙趣横生的算法(C++语言实现)
胡浩 / 清华大学出版社 / 2014-10-1 / 59.80元
《妙趣横生的算法(C++语言实现)》内容丰富,生动有趣,寓教于乐,旨在帮助读者学习数据结构和算法的相关知识,从而开阔眼界,培养编程兴趣,提高编程能力,增强求职的竞争力。如果您想提高自己对算法和数据结构的理解能力,在程序设计之路上走得更远,那么请翻开《妙趣横生的算法(C++语言实现)》,仔细研读吧,它将助您一臂之力。 《妙趣横生的算法(C++语言实现)》以通俗易懂的语言深入浅出地介绍了常用的数......一起来看看 《妙趣横生的算法(C++语言实现)》 这本书的介绍吧!