From 008f6f5d4e9d04c8709c3658fff93fe4e327ac09 Mon Sep 17 00:00:00 2001 From: Emil Mikulic Date: Wed, 13 Dec 2006 13:07:10 +0000 Subject: [PATCH] We can handle a request from accept() to close() without having to go through a single iteration of the select() loop. This commit re-orders the way state == DONE is handled so that keep-alive connections can go straight back into recv_request without visiting select(). Unfortunately, this doesn't fix the keep-alive performance. --- trunk/darkhttpd.c | 65 +++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/trunk/darkhttpd.c b/trunk/darkhttpd.c index beaa41d..5d2d38f 100644 --- a/trunk/darkhttpd.c +++ b/trunk/darkhttpd.c @@ -2279,18 +2279,8 @@ static void httpd_poll(void) switch (conn->state) { case DONE: - /* clean out stale connections while we're at it */ - if (conn->conn_close) - { - LIST_REMOVE(conn, entries); - free_connection(conn); - free(conn); - break; - } - /* else */ - recycle_connection(conn); - /* And enqueue as RECV_REQUEST. */ - /* FALLTHROUGH */ + /* do nothing */ + break; case RECV_REQUEST: MAX_FD_SET(conn->socket, &recv_set); @@ -2328,26 +2318,45 @@ static void httpd_poll(void) /* poll connections that select() says need attention */ if (FD_ISSET(sockin, &recv_set)) accept_connection(); - LIST_FOREACH(conn, &connlist, entries) - switch (conn->state) - { - case RECV_REQUEST: - if (FD_ISSET(conn->socket, &recv_set)) poll_recv_request(conn); - break; + LIST_FOREACH(conn, &connlist, entries) { + switch (conn->state) + { + case RECV_REQUEST: + if (FD_ISSET(conn->socket, &recv_set)) poll_recv_request(conn); + break; - case SEND_HEADER: - if (FD_ISSET(conn->socket, &send_set)) poll_send_header(conn); - break; + case SEND_HEADER: + if (FD_ISSET(conn->socket, &send_set)) poll_send_header(conn); + break; - case SEND_REPLY: - if (FD_ISSET(conn->socket, &send_set)) poll_send_reply(conn); - break; + case SEND_REPLY: + if (FD_ISSET(conn->socket, &send_set)) poll_send_reply(conn); + break; - case DONE: - /* do nothing (FIXME) */ - break; + case DONE: + /* (handled later; ignore for now as it's a valid state) */ + break; - default: errx(1, "invalid state"); + default: errx(1, "invalid state"); + } + + if (conn->state == DONE) { + /* clean out finished connection */ + if (conn->conn_close) + { + LIST_REMOVE(conn, entries); + free_connection(conn); + free(conn); + break; + } + /* else */ + recycle_connection(conn); + + /* and go right back to recv_request without going through + * select() again. + */ + poll_recv_request(conn); + } } }