libmicrohttpd

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

commit 4c219bf5c0d4685cb00fd7ce19dd871348b67833
parent aac24654135d0e816900f4b95536fa95d78d49af
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Tue, 14 Mar 2017 23:55:16 +0300

Prevent calling of MHD_get_fdset() and MHD_get_fdset2() for daemons with MHD_USE_INTERNAL_POLLING_THREAD,
maintain backward compatibility

Diffstat:
Msrc/include/microhttpd.h | 9+++++++++
Msrc/microhttpd/daemon.c | 129++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
2 files changed, 100 insertions(+), 38 deletions(-)

diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h @@ -2153,6 +2153,9 @@ MHD_add_connection (struct MHD_Daemon *daemon, * before calling this function. FD_SETSIZE is assumed * to be platform's default. * + * This function could be called only for daemon started + * without MHD_USE_INTERNAL_POLLING_THREAD flag. + * * @param daemon daemon to get sets from * @param read_fd_set read set * @param write_fd_set write set @@ -2181,6 +2184,9 @@ MHD_get_fdset (struct MHD_Daemon *daemon, * as @a fd_setsize allow usage of larger/smaller than * platform's default fd_sets. * + * This function could be called only for daemon started + * without MHD_USE_INTERNAL_POLLING_THREAD flag. + * * @param daemon daemon to get sets from * @param read_fd_set read set * @param write_fd_set write set @@ -2210,6 +2216,9 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, * before calling this function. Size of fd_set is * determined by current value of FD_SETSIZE. * + * This function could be called only for daemon started + * without MHD_USE_INTERNAL_POLLING_THREAD flag. + * * @param daemon daemon to get sets from * @param read_fd_set read set * @param write_fd_set write set diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c @@ -889,13 +889,9 @@ urh_from_pollfd(struct MHD_UpgradeResponseHandle *urh, } #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ + /** - * Obtain the `select()` sets for this daemon. - * Daemon's FDs will be added to fd_sets. To get only - * daemon FDs in fd_sets, call FD_ZERO for each fd_set - * before calling this function. Passing custom FD_SETSIZE - * as @a fd_setsize allow usage of larger/smaller than - * platform's default fd_sets. + * Internal version of #MHD_get_fdset2(). * * @param daemon daemon to get sets from * @param read_fd_set read set @@ -904,44 +900,27 @@ urh_from_pollfd(struct MHD_UpgradeResponseHandle *urh, * @param max_fd increased to largest FD added (if larger * than existing value); can be NULL * @param fd_setsize value of FD_SETSIZE - * @return #MHD_YES on success, #MHD_NO if this - * daemon was not started with the right - * options for this call or any FD didn't + * @return #MHD_YES on success, #MHD_NO if any FD didn't * fit fd_set. * @ingroup event */ int -MHD_get_fdset2 (struct MHD_Daemon *daemon, - fd_set *read_fd_set, - fd_set *write_fd_set, - fd_set *except_fd_set, - MHD_socket *max_fd, - unsigned int fd_setsize) +internal_get_fdset2 (struct MHD_Daemon *daemon, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *except_fd_set, + MHD_socket *max_fd, + unsigned int fd_setsize) + { struct MHD_Connection *pos; struct MHD_Connection *posn; int result = MHD_YES; MHD_socket ls; - if ( (NULL == daemon) || - (NULL == read_fd_set) || - (NULL == write_fd_set) || - (daemon->shutdown) || - (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || - (0 != (daemon->options & MHD_USE_POLL))) + if (daemon->shutdown) return MHD_NO; -#ifdef EPOLL_SUPPORT - if (0 != (daemon->options & MHD_USE_EPOLL)) - { - /* we're in epoll mode, use the epoll FD as a stand-in for - the entire event set */ - return MHD_add_to_fd_set_ (daemon->epoll_fd, - read_fd_set, - max_fd, - fd_setsize) ? MHD_YES : MHD_NO; - } -#endif ls = daemon->listen_fd; if ( (MHD_INVALID_SOCKET != ls) && (! daemon->was_quiesced) && @@ -1043,6 +1022,80 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, /** + * Obtain the `select()` sets for this daemon. + * Daemon's FDs will be added to fd_sets. To get only + * daemon FDs in fd_sets, call FD_ZERO for each fd_set + * before calling this function. Passing custom FD_SETSIZE + * as @a fd_setsize allow usage of larger/smaller than + * platform's default fd_sets. + * + * This function could be called only for daemon started + * without MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon daemon to get sets from + * @param read_fd_set read set + * @param write_fd_set write set + * @param except_fd_set except set + * @param max_fd increased to largest FD added (if larger + * than existing value); can be NULL + * @param fd_setsize value of FD_SETSIZE + * @return #MHD_YES on success, #MHD_NO if this + * daemon was not started with the right + * options for this call or any FD didn't + * fit fd_set. + * @ingroup event + */ +int +MHD_get_fdset2 (struct MHD_Daemon *daemon, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *except_fd_set, + MHD_socket *max_fd, + unsigned int fd_setsize) +{ + fd_set es; + + if ( (NULL == daemon) || + (NULL == read_fd_set) || + (NULL == write_fd_set) || + (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || + (0 != (daemon->options & MHD_USE_POLL))) + return MHD_NO; + + if (NULL == except_fd_set) + { /* Workaround to maintain backward compatibility. */ +#ifdef HAVE_MESSAGES + MHD_DLOG (daemon, + _("MHD_get_fdset2() called with except_fd_set " + "set to NULL. Such behavior is unsupported.\n")); +#endif + except_fd_set = es; + FD_ZERO(except_fd_set); + } + +#ifdef EPOLL_SUPPORT + if (0 != (daemon->options & MHD_USE_EPOLL)) + { + if (daemon->shutdown) + return MHD_NO; + + /* we're in epoll mode, use the epoll FD as a stand-in for + the entire event set */ + + return MHD_add_to_fd_set_ (daemon->epoll_fd, + read_fd_set, + max_fd, + fd_setsize) ? MHD_YES : MHD_NO; + } +#endif + + return internal_get_fdset2 (daemon, read_fd_set, + write_fd_set, except_fd_set, + max_fd, fd_setsize); +} + + +/** * Call the handlers for a connection in the appropriate order based * on the readiness as detected by the event loop. * @@ -3397,12 +3450,12 @@ MHD_select (struct MHD_Daemon *daemon, /* single-threaded, go over everything */ if (MHD_NO == - MHD_get_fdset2 (daemon, - &rs, - &ws, - &es, - &maxsock, - FD_SETSIZE)) + internal_get_fdset2 (daemon, + &rs, + &ws, + &es, + &maxsock, + FD_SETSIZE)) { #ifdef HAVE_MESSAGES MHD_DLOG (daemon,