libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 813fc203ef95f7e3b1d410e182d363a30f5fdad3
parent 0e0822dd3e6e7b3c3a1ff1f2501fe40481932429
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Tue, 21 Feb 2017 21:34:39 +0300

call_handlers(): always call idle_handler() after each read/write. This allow to process both
read and write at single call_handlers() invocation if readability and writeability are
both known (epoll mode).
Simplified checks for 'fast track' mode.

Diffstat:
Msrc/microhttpd/daemon.c | 56+++++++++++++++++++++++++++++++++-----------------------
1 file changed, 33 insertions(+), 23 deletions(-)

diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c @@ -886,8 +886,8 @@ call_handlers (struct MHD_Connection *con, bool force_close) { int ret; - /* Initial state of connection. */ - bool was_initing = (con->state == MHD_CONNECTION_INIT); + /* Fast track flag */ + bool on_fasttrack = (con->state == MHD_CONNECTION_INIT); #ifdef HTTPS_SUPPORT if (con->tls_read_ready) @@ -896,15 +896,24 @@ call_handlers (struct MHD_Connection *con, if (!force_close) { if (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info && read_ready) - con->read_handler (con); + { + con->read_handler (con); + ret = con->idle_handler (con); + } + /* No need to check value of 'ret' here as closed connection + * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */ if (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info && write_ready) - con->write_handler (con); + { + con->write_handler (con); + ret = con->idle_handler (con); + } } else - MHD_connection_close_ (con, - MHD_REQUEST_TERMINATED_WITH_ERROR); - - ret = con->idle_handler (con); + { + MHD_connection_close_ (con, + MHD_REQUEST_TERMINATED_WITH_ERROR); + return con->idle_handler (con); + } /* Fast track for fast connections. */ /* If full request was read by single read_handler() invocation @@ -914,23 +923,24 @@ call_handlers (struct MHD_Connection *con, As writeability of socket was not checked and it may have some data pending in system buffers, use this optimization only for non-blocking sockets. */ - if ( (MHD_NO != ret) && - (was_initing) && - (MHD_CONNECTION_HEADERS_SENDING == con->state) && - (con->sk_nonblck) ) - { - con->write_handler (con); - /* If all headers were sent by single write_handler() - continue. */ - if (MHD_CONNECTION_HEADERS_SENT == con->state) + /* No need to check 'ret' as connection is always in + * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */ + if (on_fasttrack && con->sk_nonblck) + { + if (MHD_CONNECTION_HEADERS_SENDING == con->state) { + con->write_handler (con); + /* Always call 'idle_handler()' after each read/write. */ + ret = con->idle_handler (con); + } + /* If all headers were sent by single write_handler() and + * response body is prepared by single idle_handler() + * call - continue. */ + if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) || + (MHD_CONNECTION_CHUNKED_BODY_READY == con->state)) + { + con->write_handler (con); ret = con->idle_handler (con); - if ( (MHD_NO != ret) && - ( (MHD_CONNECTION_NORMAL_BODY_READY == con->state) || - (MHD_CONNECTION_CHUNKED_BODY_READY == con->state) ) ) - { - con->write_handler (con); - ret = con->idle_handler (con); - } } } return ret;