libmicrohttpd

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

commit 74e0a68567054b20e24ea79fecf1ccf2940fda9b
parent 015495e47128fa1d31ad2106a60b9654fe6e0666
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon, 25 Nov 2013 21:51:08 +0000

-fixes to MHD_suspend_connection

Diffstat:
MAUTHORS | 1+
MChangeLog | 5+++++
Mconfigure.ac | 2+-
Msrc/microhttpd/connection.c | 7++++++-
Msrc/microhttpd/daemon.c | 91+++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/microhttpd/internal.h | 8++++++--
6 files changed, 68 insertions(+), 46 deletions(-)

diff --git a/AUTHORS b/AUTHORS @@ -44,6 +44,7 @@ Brecht Sanders <brecht@sanders.org> Jan Janak <jan@janakj.org> Matthew Mundell <matthew.mundell@greenbone.net> Scott Goldman <scottjg@github.com> +Jared Cantwell Documentation contributions also came from: Marco Maggi <marco.maggi-ipsu@poste.it> diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,8 @@ +Sun Nov 24 13:41:15 CET 2013 + Introduce state to mark connections in suspended state (with + epoll); add missing locking operations in MHD_suspend_connection. + Fix definition of MHD_TLS_CONNECTION_INIT. -MH/JC + Wed Oct 30 09:34:20 CET 2013 Fixing issue in PostProcessor when getting partial boundary at the beginning, expanding test suite. -CG diff --git a/configure.ac b/configure.ac @@ -22,7 +22,7 @@ # AC_PREREQ(2.57) AC_INIT([libmicrohttpd], [0.9.31],[libmicrohttpd@gnu.org]) -AM_INIT_AUTOMAKE([silent-rules serial-tests]) +AM_INIT_AUTOMAKE([silent-rules]) AC_CONFIG_HEADERS([MHD_config.h]) AC_CONFIG_MACRO_DIR([m4]) AH_TOP([#define _GNU_SOURCE 1]) diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c @@ -2474,6 +2474,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) { case MHD_EVENT_LOOP_INFO_READ: if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) && + (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) && (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) ) { EDLL_insert (daemon->eready_head, @@ -2485,6 +2486,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) case MHD_EVENT_LOOP_INFO_WRITE: if ( (connection->read_buffer_size > connection->read_buffer_offset) && (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) && + (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) && (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) ) { EDLL_insert (daemon->eready_head, @@ -2493,6 +2495,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; } if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) && + (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) && (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) ) { EDLL_insert (daemon->eready_head, @@ -2504,7 +2507,8 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) case MHD_EVENT_LOOP_INFO_BLOCK: /* we should look at this connection again in the next iteration of the event loop, as we're waiting on the application */ - if (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) + if ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) && + (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED))) ) { EDLL_insert (daemon->eready_head, daemon->eready_tail, @@ -2539,6 +2543,7 @@ MHD_connection_epoll_update_ (struct MHD_Connection *connection) if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) && + (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) && ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) || ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) && ( (MHD_EVENT_LOOP_INFO_READ == connection->event_loop_info) || diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c @@ -1398,6 +1398,9 @@ MHD_suspend_connection (struct MHD_Connection *connection) daemon = connection->daemon; if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) MHD_PANIC ("Cannot suspend connections in THREAD_PER_CONNECTION mode!\n"); + if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && + (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) ) + MHD_PANIC ("Failed to acquire cleanup mutex\n"); DLL_remove (daemon->connections_head, daemon->connections_tail, connection); @@ -1410,22 +1413,29 @@ MHD_suspend_connection (struct MHD_Connection *connection) daemon->manual_timeout_tail, connection); #if EPOLL_SUPPORT - if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) - { - EDLL_remove (daemon->eready_head, - daemon->eready_tail, - connection); - } - if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) - { - if (0 != epoll_ctl (daemon->epoll_fd, - EPOLL_CTL_DEL, - connection->socket_fd, - NULL)) - MHD_PANIC ("Failed to remove FD from epoll set\n"); - connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; - } + if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) + { + if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) + { + EDLL_remove (daemon->eready_head, + daemon->eready_tail, + connection); + } + if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) + { + if (0 != epoll_ctl (daemon->epoll_fd, + EPOLL_CTL_DEL, + connection->socket_fd, + NULL)) + MHD_PANIC ("Failed to remove FD from epoll set\n"); + connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; + } + connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED; + } #endif + if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && + (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) ) + MHD_PANIC ("Failed to release cleanup mutex\n"); } @@ -1460,33 +1470,30 @@ MHD_resume_connection (struct MHD_Connection *connection) daemon->manual_timeout_tail, connection); #if EPOLL_SUPPORT - if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) - { - EDLL_insert (daemon->eready_head, - daemon->eready_tail, - connection); - } - else - { - struct epoll_event event; - - event.events = EPOLLIN | EPOLLOUT | EPOLLET; - event.data.ptr = connection; - if (0 != epoll_ctl (daemon->epoll_fd, - EPOLL_CTL_ADD, - connection->socket_fd, - &event)) - { -#if HAVE_MESSAGES - MHD_DLOG (daemon, - "Call to epoll_ctl failed: %s\n", - STRERROR (errno)); -#endif - /* and now, good luck with this... */ - } - else - connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; - } + if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) + { + if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) + { + EDLL_insert (daemon->eready_head, + daemon->eready_tail, + connection); + } + else + { + struct epoll_event event; + + event.events = EPOLLIN | EPOLLOUT | EPOLLET; + event.data.ptr = connection; + if (0 != epoll_ctl (daemon->epoll_fd, + EPOLL_CTL_ADD, + connection->socket_fd, + &event)) + MHD_PANIC ("Failed to add FD to epoll set\n"); + else + connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; + } + connection->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED; + } #endif if ( (-1 != daemon->wpipe[1]) && (1 != WRITE (daemon->wpipe[1], "n", 1)) ) diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h @@ -116,8 +116,12 @@ enum MHD_EpollState /** * Is this connection currently in the 'epoll' set? */ - MHD_EPOLL_STATE_IN_EPOLL_SET = 8 + MHD_EPOLL_STATE_IN_EPOLL_SET = 8, + /** + * Is this connection currently suspended? + */ + MHD_EPOLL_STATE_SUSPENDED = 16 }; @@ -452,7 +456,7 @@ enum MHD_CONNECTION_STATE * Handshake messages will be processed in this state & while * in the 'MHD_TLS_HELLO_REQUEST' state */ - MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_CLOSED + 1 + MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_IN_CLEANUP + 1 };