1. 所在的结构体定义
sock_t listening_sock;
union socket_address lsa; // Listening socket address
struct ll active_connections;
struct ll uri_handlers;
char *config_options[NUM_OPTIONS];
void *server_data;
void *ssl_ctx; // SSL context
sock_t ctl[2]; // Control socketpair. Used to wake up from select() call
};
active_connections是一个双向循环链表:
struct ll { struct ll *prev, *next; };
2. 变量初始化
mg_create_server函数:
LINKED_LIST_INIT(&server->active_connections);
#define LINKED_LIST_INIT(N) ((N)->next = (N)->prev = (N))
3. 向链表中添加元素
accept_new_connection函数
该函数又是一个高级的if else if else的写法,作者的意图操作是:
- if(执行一个语句并判断)
- else if(再执行一个语句并判断) {异常处理}
- else if(再执行一个语句并判断) {异常处理}
- else {最终执行一些操作}
这里的厉害之处就在于:
每次if或者else if执行完语句后,故意让预期表达式为false,同而可以执行下一个分支,这样正常情况下,上面的三个if或else if判断中的表达式都会执行到,同时保证最终进入到else中完成所有的处理。
下面来分析函数的具体作用:
- sock = accept(server->listening_sock, &sa.sa, &len) accept一个连接
- check_acl(server->config_options[ACCESS_CONTROL_LIST], ntohl(* (uint32_t *) &sa.sin.sin_addr) 检查连接不是acl ACCESS_CONTROL_LIST
- conn = (struct connection *) calloc(1, sizeof(*conn)) calloc一个struct connection大小的空间,将指针赋给conn
- set_close_on_exec(sock); and set_non_blockin