Fix timeouts to close connections.

This commit is contained in:
Emil Mikulic 2018-12-10 00:54:12 +11:00
parent dcb89f3d0f
commit 89af6956e2
2 changed files with 10 additions and 4 deletions

2
TODO
View File

@ -1,3 +1,5 @@
- keepalive performance against ab sucks - keepalive performance against ab sucks
- keepalive+TCP_NODELAY hangs! - keepalive+TCP_NODELAY hangs!
- send headers using sendfile syscall - fewer packets - send headers using sendfile syscall - fewer packets
- make timeout a cmdline arg
- add test for timeout

View File

@ -1331,7 +1331,7 @@ static void poll_check_timeout(struct connection *conn) {
if (idletime > 0) { /* optimised away by compiler */ if (idletime > 0) { /* optimised away by compiler */
if (now - conn->last_active >= idletime) { if (now - conn->last_active >= idletime) {
if (debug) if (debug)
printf("poll_check_timeout(%d) caused closure\n", printf("poll_check_timeout(%d) closing connection\n",
conn->socket); conn->socket);
conn->conn_close = 1; conn->conn_close = 1;
conn->state = DONE; conn->state = DONE;
@ -2343,7 +2343,6 @@ static void httpd_poll(void) {
if (accepting) MAX_FD_SET(sockin, &recv_set); if (accepting) MAX_FD_SET(sockin, &recv_set);
LIST_FOREACH_SAFE(conn, &connlist, entries, next) { LIST_FOREACH_SAFE(conn, &connlist, entries, next) {
poll_check_timeout(conn);
switch (conn->state) { switch (conn->state) {
case DONE: case DONE:
/* do nothing */ /* do nothing */
@ -2364,13 +2363,14 @@ static void httpd_poll(void) {
#undef MAX_FD_SET #undef MAX_FD_SET
/* -select- */ /* -select- */
if (debug)
printf("select() with max_fd %d timeout %d\n",
max_fd, bother_with_timeout ? (int)timeout.tv_sec : 0);
select_ret = select(max_fd + 1, &recv_set, &send_set, NULL, select_ret = select(max_fd + 1, &recv_set, &send_set, NULL,
(bother_with_timeout) ? &timeout : NULL); (bother_with_timeout) ? &timeout : NULL);
if (select_ret == 0) { if (select_ret == 0) {
if (!bother_with_timeout) if (!bother_with_timeout)
errx(1, "select() timed out"); errx(1, "select() timed out");
else
return;
} }
if (select_ret == -1) { if (select_ret == -1) {
if (errno == EINTR) if (errno == EINTR)
@ -2378,6 +2378,8 @@ static void httpd_poll(void) {
else else
err(1, "select() failed"); err(1, "select() failed");
} }
if (debug)
printf("select() returned %d\n", select_ret);
/* update time */ /* update time */
now = time(NULL); now = time(NULL);
@ -2387,6 +2389,7 @@ static void httpd_poll(void) {
accept_connection(); accept_connection();
LIST_FOREACH_SAFE(conn, &connlist, entries, next) { LIST_FOREACH_SAFE(conn, &connlist, entries, next) {
poll_check_timeout(conn);
switch (conn->state) { switch (conn->state) {
case RECV_REQUEST: case RECV_REQUEST:
if (FD_ISSET(conn->socket, &recv_set)) poll_recv_request(conn); if (FD_ISSET(conn->socket, &recv_set)) poll_recv_request(conn);
@ -2405,6 +2408,7 @@ static void httpd_poll(void) {
break; break;
} }
/* Handling SEND_REPLY could have set the state to done. */
if (conn->state == DONE) { if (conn->state == DONE) {
/* clean out finished connection */ /* clean out finished connection */
if (conn->conn_close) { if (conn->conn_close) {