本节开始分析lighttpd中处理连接的状态机,也就是connections.c文件中的connection_state_machine函数.我们将沿着上一节中给出的状态机示意图一步一步往下走,以图把这个过程分析清楚.这也是目前为止唯一一个详细进行分析的函数,希望这样可以更加突出这个函数的重要性.
一)CON_STATE_REQUEST_START状态
这个状态出现在刚刚通过accept函数接收一个新的连接时,此时需要保存一些数据:
case CON_STATE_REQUEST_START: /* transient, 开始接收请求 */
if (srv->srvconf.log_state_handling) {
log_error_write(srv, __FILE__, __LINE__, "sds",
"state for fd", con->fd, connection_get_state(con->state));
}
// 保存时间
con->request_start = srv->cur_ts;
con->read_idle_ts = srv->cur_ts;
// 该连接的请求次数
con->request_count++;
// 每次循环处理的请求次数
con->loops_per_request = 0;
// 状态改为可读, 也就是可以接收数据
connection_set_state(srv, con, CON_STATE_READ);
/* patch con->conf.is_ssl if the connection is a ssl-socket already */
#ifdef USE_OPENSSL
con->conf.is_ssl = srv_sock->is_ssl;
#endif
break;
需要注意的是这里将connetion中的两个字段保存为当前时间,request_start和read_idle_ts, 前者存放的是接收连接的时间, 后者用于超时判断, 在第5节讲解lighttpd中如何处理超时的时候提到过,lighttpd设置了一个每一秒一次的定时器, 每次定时器到时就依次轮询所有的连接, 判断是否超时, 而判断的依据就是拿当前的时间 - connection的read_idle_ts字段, 看看是否超时:
// 如果当前时间与read_idle_ts之差大于max_read_idle, 超时
if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
/* time - out */
connection_set_state(srv, con, CON_STATE_ERROR);
changed = 1;
}
这些该保存的数据都保存完毕之后, 状态机进入下一个状态,CON_STATE_READ, 也就是开始接收数据, 这是下一节要讲解的内容了.