boa应用程序从src/boa.c开始运行,进入关键的select_loop中,boa将处于无阻塞轮询运行服务中。
/* boa里边有三个请求链表
* request *request_ready = NULL; /* ready list head */
* request *request_block = NULL; /* blocked list head */
* request *request_free = NULL; /* free list head */
*
/
#include "boa.h"
static void fdset_update(void);
fd_set block_read_fdset;
fd_set block_write_fdset;
static struct timeval req_timeout; /* timeval for select */
void select_loop(int server_s)
{
FD_ZERO(&block_read_fdset); //清空,block_read_fdset、block_write_fdset;
FD_ZERO(&block_write_fdset);
/* set server_s and req_timeout */ //设置server_s和请求超时时间。
req_timeout.tv_sec = (ka_timeout ? ka_timeout : REQUEST_TIMEOUT);
req_timeout.tv_usec = 0l; /* reset timeout */
/* preset max_fd */
max_fd = -1;
while (1) { //进入web server服务主循环
if (sighup_flag) //处理sighup 、 sigchld 、 sigalrm、 sigterm等信号。
sighup_run();
if (sigchld_flag)
sigchld_run();
if (sigalrm_flag)
sigalrm_run();
if (sigterm_flag) {
if (sigterm_flag == 1)
sigterm_stage1_run(server_s);
if (sigterm_flag == 2 && !request_ready && !request_block) {
sigterm_stage2_run();
}
}
/* reset max_fd */
max_fd = -1; //重置max_fd为-1;
if (request_block) //如果request_block里面有request,则将合适的request从block链表里移到ready链表里。
/* move selected req's from request_block to request_ready */
fdset_update();
/* any blocked req's move from request_ready to request_block */
process_requests(server_s); //处理request ,将blocked request从ready链移至block链
if (!sigterm_flag && total_connections < (max_connections - 10)) {
BOA_FD_SET(server_s, &block_read_fdset); /* server always set */
}
//重置时间
req_timeout.tv_sec = (request_ready ? 0 :
(ka_timeout ? ka_timeout : REQUEST_TIMEOUT));
req_timeout.tv_usec = 0l; /* reset timeout */
if (select(max_fd + 1, &block_read_fdset, //进入select轮询
&block_write_fdset, NULL,
(request_ready || request_block ? &req_timeout : NULL)) &