在globals.h中定义了一个描述请求的结构体request。它实际上是一个链表结构。
三个链表
接着定义了三个链表:
extern request *request_ready; /* first in ready list */
extern request *request_block; /* first in blocked list */
extern request *request_free; /* first in free list */
如果request_block不为空,fdset_update将合适的request从block链表里移动到ready链表里。
if (request_block)
fdset_update();
fdset_update的作用是:
iterate through the blocked requests, checking whether that file descriptor has been set by select. Update the fd_set to reflect current status.
fdset_update进行如下处理:
case1: ka(keepalive?)超时,则把current状态赋为dead。
case2: 请求超时,则把current状态赋为dead。
case3:缓冲区有数据,而且status不是DEAD。如果fd不在block_write_fdset里,那么放到block_write_fdset里。如果fd已经在block_write_fdset里,调用ready_request,将request从block队列里转移到ready队列里,同时清除block_write_fdset里的标志。
case4:状态为WRITE,PIPE_WRITE,DONE的请求,如果没有就放到block_write_fdset里,如果已经在了就调用ready_request。
状态为BODY_WRITE,将request的post_data_fd做以上处理。
状态为PIPE_READ,将request的data_fd做类似处理,不过检查的是block_read_fdset。
状态为DEAD,直接调用ready_request。其他的,检查fd是否在block_read_fdset,并作相应处理
process_requests()
它的作用在源码中有描述
Description: Iterates through the ready queue, passing each request to the appropriate handler for processing. It monitors the return value from handler functions, all of which return -1 to indicate a block, 0 on completion and 1 to remain on the ready list for more procesing。
在ready queue中遍历,把每个请求分发给适当的处理函数。同时监测处理函数的返回值。返回-1表示阻塞,0表示完成,1表示仍然在ready list中进行处理。
如果pending_requests标志置为1,会执行get_request(server_s)。
然后是select的核心部分。
if (select(max_fd + 1, &block_read_fdset,&block_write_fdset,
NULL,(request_ready || request_block ? &req_timeout : NULL)) == -1)
{
if (errno == EINTR) continue;
else if (errno != EBADF) {
DIE("select");}
}
select检查可读性和可写性,request_ready和request_block都为空(NULL)则一直等待。
算法流程
算法流程图如下所示
在select_loop中的while(1)循环中做这些事情:
1.检查各种信号是否发生。
2.将阻塞队列的请求更新到就绪队列。
3.处理就绪队列的请求,并进行网页处理。block_read_fdset和block_write_fdset的更新在fdset_update和process_requests这两个函数里进行。
4.设置server_s,并调用select。
5.如果有新连接,置pending_requests为1,延时到fdset_update或process_requests里处理。
这就是整个BOA服务器源码的笔记。还有很多细节没有看,主要是了解下流程和原理。
Reference
[1].http://blog.csdn.net/tricky1997/article/details/6954299
[2].http://blog.csdn.net/duola_rain/article/details/12569579