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

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

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


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

查看所有标签

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

Persuasive Technology

Persuasive Technology

B.J. Fogg / Morgan Kaufmann / 2002-12 / USD 39.95

Can computers change what you think and do? Can they motivate you to stop smoking, persuade you to buy insurance, or convince you to join the Army? "Yes, they can," says Dr. B.J. Fogg, directo......一起来看看 《Persuasive Technology》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具