libmicrohttpd

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

commit 71f2285bff70ac45ecf846de203016322997f995
parent dc9b5154aeff904ec8801d4144e3c0a996e15be5
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon, 17 Oct 2016 15:34:42 +0200

implement early thread-termination for upgraded HTTP connections logic

Diffstat:
Msrc/microhttpd/daemon.c | 24++++++++++++++++--------
Msrc/microhttpd/response.c | 41+++++++++++++++++++++++++++++++++--------
Msrc/microhttpd/test_upgrade.c | 5-----
3 files changed, 49 insertions(+), 21 deletions(-)

diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c @@ -1281,13 +1281,6 @@ thread_main_connection_upgrade (struct MHD_Connection *con) #endif /* end HTTPS */ #endif - - /* Here, we need to block until the application - signals us that it is done with the socket */ - MHD_semaphore_down (con->upgrade_sem); - MHD_semaphore_destroy (con->upgrade_sem); - con->upgrade_sem = NULL; - MHD_cleanup_upgraded_connection_ (con); } @@ -1533,7 +1526,22 @@ thread_main_handle_connection (void *data) if (MHD_CONNECTION_UPGRADE == con->state) { thread_main_connection_upgrade (con); - break; +#if HTTPS_SUPPORT + if (0 != (daemon->options & MHD_USE_TLS) ) + break; +#endif + + /* skip usual clean up EXCEPT for the completion + notification (which must be done in this thread)! */ + if ( (NULL != daemon->notify_completed) && + (MHD_YES == con->client_aware) ) + daemon->notify_completed (daemon->notify_completed_cls, + con, + &con->client_context, + MHD_REQUEST_TERMINATED_COMPLETED_OK); + con->client_aware = MHD_NO; + + return (MHD_THRD_RTRN_TYPE_) 0; } } if (MHD_CONNECTION_IN_CLEANUP != con->state) diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c @@ -642,14 +642,6 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh, SHUT_RDWR); } #endif - /* Application is done with this connection, tear it down! */ - if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION) ) - { - /* need to signal the thread that we are done */ - MHD_semaphore_up (connection->upgrade_sem); - /* connection and urh cleanup will be done in connection's thread */ - return MHD_YES; - } #if HTTPS_SUPPORT if (0 != (daemon->options & MHD_USE_TLS) ) { @@ -659,6 +651,39 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh, return MHD_YES; } #endif + /* Application is done with this connection, tear it down! */ + if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION) ) + { + /* need to finish connection clean up */ + MHD_cleanup_upgraded_connection_ (connection); + if (MHD_CONNECTION_IN_CLEANUP != connection->state) + { +#if DEBUG_CLOSE +#ifdef HAVE_MESSAGES + MHD_DLOG (connection->daemon, + _("Processing thread terminating. Closing connection\n")); +#endif +#endif + if (MHD_CONNECTION_CLOSED != connection->state) + MHD_connection_close_ (connection, + MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); + connection->idle_handler (connection); + } + if (NULL != connection->response) + { + MHD_destroy_response (connection->response); + connection->response = NULL; + } + + if (MHD_INVALID_SOCKET != connection->socket_fd) + { + shutdown (connection->socket_fd, + SHUT_WR); + MHD_socket_close_chk_ (connection->socket_fd); + connection->socket_fd = MHD_INVALID_SOCKET; + } + return MHD_YES; + } /* 'upgraded' resources are not needed anymore - cleanup now */ MHD_cleanup_upgraded_connection_ (connection); return MHD_YES; diff --git a/src/microhttpd/test_upgrade.c b/src/microhttpd/test_upgrade.c @@ -104,8 +104,6 @@ main (int argc, int error_count = 0; /* try external select */ -#if 0 - error_count += test_upgrade (0, 0); #ifdef EPOLL_SUPPORT @@ -122,9 +120,6 @@ main (int argc, /* Test different event loops, with and without thread pool */ error_count += test_upgrade (MHD_USE_SELECT_INTERNALLY, 0); - -#endif - error_count += test_upgrade (MHD_USE_SELECT_INTERNALLY, 2); #ifdef HAVE_POLL