wifidog源码分析Lighttpd1.4.20源码分析之fdevent系统(2)-----初始化(2)

栏目: 服务器 · 发布时间: 6年前

内容简介: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 整理编辑,转载请注明出处


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

创新者的窘境(全新修订版)

创新者的窘境(全新修订版)

克莱顿•克里斯坦森 / 胡建桥 / 中信出版社 / 2014-1-1 / 48.00元

全球商业领域中,许多企业曾叱咤风云,但面对市场变化及新技术的挑战,最终惨遭淘汰。究其原因,竟然是因为它们精于管理,信奉客户至上等传统商业观念。这就是所有企业如今都正面临的“创新者的窘境”。 在《创新者的窘境》中,管理大师克里斯坦森指出,一些看似很完美的商业动作——对主流客户所需、赢利能力最强的产品进行精准投资和技术研发——最终却很可能毁掉一家优秀的企业。他分析了计算机、汽车、钢铁等多个行业的......一起来看看 《创新者的窘境(全新修订版)》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具