diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-11-09 23:14:01 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-11-10 17:11:35 +0300 |
commit | 51c1f5e65bff0eee79d87874ee5b8f1514c38032 (patch) | |
tree | 58305e8749e7051492b99dbe0b41de198dd57b0a /src/microhttpd/daemon.c | |
parent | e05239e5c7c6d073fcc2500c59d3b1c39e44169d (diff) | |
download | libmicrohttpd-51c1f5e65bff0eee79d87874ee5b8f1514c38032.tar.gz libmicrohttpd-51c1f5e65bff0eee79d87874ee5b8f1514c38032.zip |
Use non-blocking sockets for fast responses
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 74 |
1 files changed, 39 insertions, 35 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index ae6aaeed..fda82836 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -889,8 +889,9 @@ call_handlers (struct MHD_Connection *con, | |||
889 | int force_close) | 889 | int force_close) |
890 | { | 890 | { |
891 | struct MHD_Daemon *daemon = con->daemon; | 891 | struct MHD_Daemon *daemon = con->daemon; |
892 | int had_response_before_idle; | ||
893 | int ret; | 892 | int ret; |
893 | /* Initial state of connection. */ | ||
894 | bool was_initing = (con->state == MHD_CONNECTION_INIT); | ||
894 | 895 | ||
895 | #ifdef HTTPS_SUPPORT | 896 | #ifdef HTTPS_SUPPORT |
896 | if (MHD_YES == con->tls_read_ready) | 897 | if (MHD_YES == con->tls_read_ready) |
@@ -900,25 +901,37 @@ call_handlers (struct MHD_Connection *con, | |||
900 | con->read_handler (con); | 901 | con->read_handler (con); |
901 | if (write_ready) | 902 | if (write_ready) |
902 | con->write_handler (con); | 903 | con->write_handler (con); |
903 | had_response_before_idle = (NULL != con->response); | ||
904 | if (force_close) | 904 | if (force_close) |
905 | MHD_connection_close_ (con, | 905 | MHD_connection_close_ (con, |
906 | MHD_REQUEST_TERMINATED_WITH_ERROR); | 906 | MHD_REQUEST_TERMINATED_WITH_ERROR); |
907 | ret = con->idle_handler (con); | 907 | ret = con->idle_handler (con); |
908 | /* If we're in TURBO mode, and got a response object, | 908 | |
909 | try opportunistically to just call write immediately. */ | 909 | /* Fast track for fast connections. */ |
910 | if ( (! force_close) && | 910 | /* If full request was read by single read_handler() invocation |
911 | (MHD_YES == ret) && | 911 | and headers were completely prepared by single idle_handler() |
912 | (0 != (daemon->options & MHD_USE_EPOLL_TURBO)) && | 912 | then try not to wait for next sockets polling and send response |
913 | (NULL != con->response) && | 913 | immediately. |
914 | (MHD_NO == had_response_before_idle) ) | 914 | As writeability of socket was not checked and it may have |
915 | { | 915 | some data pending in system buffers, use this optimization |
916 | /* first 'write' gets the header, then 'idle' | 916 | only for non-blocking sockets. */ |
917 | readies the body, then 2nd 'write' may send | 917 | if ( (MHD_NO != ret) && |
918 | the body. */ | 918 | (was_initing) && |
919 | (MHD_CONNECTION_HEADERS_SENDING == con->state) && | ||
920 | (con->sk_nonblck) ) | ||
921 | { | ||
919 | con->write_handler (con); | 922 | con->write_handler (con); |
920 | if (MHD_YES == (ret = con->idle_handler (con))) | 923 | /* If all headers were sent by single write_handler() - continue. */ |
921 | con->write_handler (con); | 924 | if (MHD_CONNECTION_HEADERS_SENT == con->state) |
925 | { | ||
926 | ret = con->idle_handler (con); | ||
927 | if ( (MHD_NO != ret) && | ||
928 | ( (MHD_CONNECTION_NORMAL_BODY_READY == con->state) || | ||
929 | (MHD_CONNECTION_CHUNKED_BODY_READY == con->state) ) ) | ||
930 | { | ||
931 | con->write_handler (con); | ||
932 | ret = con->idle_handler (con); | ||
933 | } | ||
934 | } | ||
922 | } | 935 | } |
923 | return ret; | 936 | return ret; |
924 | } | 937 | } |
@@ -2126,28 +2139,16 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
2126 | connection->daemon = daemon; | 2139 | connection->daemon = daemon; |
2127 | connection->last_activity = MHD_monotonic_sec_counter(); | 2140 | connection->last_activity = MHD_monotonic_sec_counter(); |
2128 | 2141 | ||
2129 | /* set default connection handlers */ | 2142 | if (0 == (daemon->options & MHD_USE_TLS)) |
2130 | MHD_set_http_callbacks_ (connection); | ||
2131 | connection->recv_cls = &recv_param_adapter; | ||
2132 | connection->send_cls = &send_param_adapter; | ||
2133 | |||
2134 | if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO)) | ||
2135 | { | 2143 | { |
2136 | /* in turbo mode, we assume that non-blocking was already set | 2144 | /* set default connection handlers */ |
2137 | by 'accept4' or whoever calls 'MHD_add_connection' */ | 2145 | MHD_set_http_callbacks_ (connection); |
2138 | if (! MHD_socket_nonblocking_ (connection->socket_fd)) | 2146 | connection->recv_cls = &recv_param_adapter; |
2139 | { | 2147 | connection->send_cls = &send_param_adapter; |
2140 | #ifdef HAVE_MESSAGES | ||
2141 | MHD_DLOG (connection->daemon, | ||
2142 | _("Failed to set nonblocking mode on connection socket: %s\n"), | ||
2143 | MHD_socket_last_strerr_()); | ||
2144 | #endif | ||
2145 | } | ||
2146 | } | 2148 | } |
2147 | 2149 | else | |
2148 | #ifdef HTTPS_SUPPORT | ||
2149 | if (0 != (daemon->options & MHD_USE_TLS)) | ||
2150 | { | 2150 | { |
2151 | #ifdef HTTPS_SUPPORT | ||
2151 | connection->recv_cls = &recv_tls_adapter; | 2152 | connection->recv_cls = &recv_tls_adapter; |
2152 | connection->send_cls = &send_tls_adapter; | 2153 | connection->send_cls = &send_tls_adapter; |
2153 | connection->state = MHD_TLS_CONNECTION_INIT; | 2154 | connection->state = MHD_TLS_CONNECTION_INIT; |
@@ -2192,8 +2193,11 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
2192 | if (daemon->https_mem_trust) | 2193 | if (daemon->https_mem_trust) |
2193 | gnutls_certificate_server_set_request (connection->tls_session, | 2194 | gnutls_certificate_server_set_request (connection->tls_session, |
2194 | GNUTLS_CERT_REQUEST); | 2195 | GNUTLS_CERT_REQUEST); |
2196 | #else /* ! HTTPS_SUPPORT */ | ||
2197 | goto cleanup; | ||
2198 | #endif /* ! HTTPS_SUPPORT */ | ||
2195 | } | 2199 | } |
2196 | #endif /* HTTPS_SUPPORT */ | 2200 | |
2197 | 2201 | ||
2198 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 2202 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
2199 | { | 2203 | { |