我们仍然从server.c的main函数开始。
当完成fdevent的初始化之后,第一个需要fdevent处理的事情就是将在初始化网络的过程中得到的监听fd(socket函数的返回值)注册到fdevent系统中。
该动作调用的是network_register_fdevents()函数,定义在network.c文件中:
/**
* 在fd events系统中注册监听socket。
* 这个函数在子进程中被调用。
*/
int network_register_fdevents(server * srv)
{
size_t i;
if (-1 == fdevent_reset(srv->ev)){
return -1;}
/*
* register fdevents after reset
*/
/* 遍历所有的监听fd并将其注册到fdevent系统中 */
for (i = 0; i < srv->srv_sockets.used; i++)
{
server_socket *srv_socket = srv->srv_sockets.ptr[i];
fdevent_register(srv->ev, srv_socket->fd, network_server_handle_fdevent, srv_socket);
fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
}
return 0;
}
在初始化网络的过程中,调用socket函数之后,将其返回值(监听fd)保存在server结构体的srv_sockets成员中,这个成员是一个server_socket_array结构体,而server_socket_array结构体是server_socket结构体的指针数组。
server_socket结构体定义如下:
typedef struct
{
sock_addr addr; //socket fd对应的的地址。
int fd; //socket()函数返回的监听fd
int fde_ndx; //和fd相同。
buffer *ssl_pemfile;
buffer *ssl_ca_file;
buffer *ssl_cipher_list;
unsigned short ssl_use_sslv2;
unsigned short use_ipv6; //标记是否使用ipv6
unsigned short is_ssl;
buffer *srv_token;
#ifdef USE_OPENSSL
SSL_CTX *ssl_ctx;
#endif
unsigned short is_proxy_ssl;
} server_socket;
fdevent_register()函数:
int fdevent_register(fdevents * ev, int fd, fdevent_handler handler, void *ctx)
{
/* 创建一个fdnode的实例,然后对其成员赋值 */
fdnode *fdn;
fdn = fdnode_init();
fdn->handler = handler;
fdn