libmicrohttpd

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

commit d528519166ae590ec3cc6b7d7dabb3e19616ff00
parent dcc664ad7ee696ba3aeb19d35f15b0b3efd292cf
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Sat, 22 Oct 2016 11:26:31 +0300

Added support for suspending connection in thread-per-connection mode

Diffstat:
Msrc/include/microhttpd.h | 2+-
Msrc/microhttpd/daemon.c | 97++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 87 insertions(+), 12 deletions(-)

diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h @@ -126,7 +126,7 @@ typedef intptr_t ssize_t; * Current version of the library. * 0x01093001 = 1.9.30-1. */ -#define MHD_VERSION 0x00095102 +#define MHD_VERSION 0x00095103 /** * MHD-internal return code for "YES". diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c @@ -38,6 +38,10 @@ #include "mhd_itc.h" #include "mhd_compat.h" +#ifdef HAVE_STDBOOL_H +#include <stdbool.h> +#endif + #if HAVE_SEARCH_H #include <search.h> #else @@ -1425,11 +1429,82 @@ thread_main_handle_connection (void *data) struct pollfd p[1 + EXTRA_SLOTS]; #endif #undef EXTRA_SLOTS +#ifdef HAVE_POLL + const _MHD_bool use_poll = (0 != (daemon->options & MHD_USE_POLL)); +#else /* ! HAVE_POLL */ + const _MHD_bool use_poll = 0; +#endif /* ! HAVE_POLL */ + _MHD_bool was_suspended; + was_suspended = 0; while ( (MHD_YES != daemon->shutdown) && (MHD_CONNECTION_CLOSED != con->state) ) { const unsigned int timeout = daemon->connection_timeout; + _MHD_bool was_suspended = 0; + + if (MHD_NO != con->suspended) + { + /* Connection was suspended, wait for resume. */ + was_suspended = !0; + if (!use_poll) + { + FD_ZERO (&rs); + if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), + &rs, + NULL, + FD_SETSIZE)) + { + #ifdef HAVE_MESSAGES + MHD_DLOG (con->daemon, + _("Failed to add FD to fd_set\n")); + #endif + goto exit; + } + if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1, + &rs, NULL, NULL, NULL)) + { + const int err = MHD_socket_get_error_(); + + if (MHD_SCKT_ERR_IS_EINTR_(err)) + continue; +#ifdef HAVE_MESSAGES + MHD_DLOG (con->daemon, + _("Error during select (%d): `%s'\n"), + err, + MHD_socket_strerr_ (err)); +#endif + break; + } + } +#ifdef HAVE_POLL + else /* use_poll */ + { + p[0].events = POLLIN; + p[0].fd = MHD_itc_r_fd_ (daemon->itc); + p[0].revents = 0; + if (0 > MHD_sys_poll_ (p, 1, -1)) + { + if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_)) + continue; +#ifdef HAVE_MESSAGES + MHD_DLOG (con->daemon, + _("Error during poll: `%s'\n"), + MHD_socket_last_strerr_ ()); +#endif + break; + } + } +#endif /* HAVE_POLL */ + MHD_itc_clear_ (daemon->itc); + continue; /* Check again for resume. */ + } /* End of "suspended" branch. */ + + if ( was_suspended && (0 != con->connection_timeout) ) + { + con->last_activity = MHD_monotonic_sec_counter(); /* Reset timeout timer. */ + was_suspended = 0; + } tvp = NULL; #if HTTPS_SUPPORT @@ -2429,7 +2504,17 @@ resume_suspended_connections (struct MHD_Daemon *daemon) pos->resuming = MHD_NO; } if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) - MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); + { + MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); + if (MHD_NO != ret) + { /* Wake up suspended connections. */ + if ( !MHD_itc_activate_(daemon->itc, "w")) +#ifdef HAVE_MESSAGES + MHD_DLOG (daemon, + _("Failed to signal resume of connection via inter-thread communication channel.")); +#endif + } + } return ret; } @@ -4750,16 +4835,6 @@ MHD_start_daemon_va (unsigned int flags, goto free_and_fail; } - if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) && - (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) ) - { -#ifdef HAVE_MESSAGES - MHD_DLOG (daemon, - _("Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_SUSPEND_RESUME is not supported.\n")); -#endif - goto free_and_fail; - } - #ifdef __SYMBIAN32__ if (0 != (flags & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION))) {