libmicrohttpd

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

commit f5631e46aaaea2317b8d6b0385e2a6c9dde8350d
parent a6462a8a940b68f6f4eab628abcfb9e6605b6652
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Tue, 11 Oct 2016 15:21:29 +0000

Always use ITC in non-blocking mode, save some system calls.

Diffstat:
Mconfigure.ac | 19+++++++++++++++++++
Msrc/microhttpd/daemon.c | 20--------------------
Msrc/microhttpd/mhd_itc.c | 3++-
Msrc/microhttpd/mhd_itc.h | 57++++++++++++++++++++++++++++++++++++---------------------
4 files changed, 57 insertions(+), 42 deletions(-)

diff --git a/configure.ac b/configure.ac @@ -647,6 +647,25 @@ AC_INCLUDES_DEFAULT use_itc='pipe' enable_itc="$use_itc" AC_DEFINE([[_MHD_ITC_PIPE]], [[1]], [Define to use pipe for inter-thread communication]) + AC_CACHE_CHECK([[whether pipe2(2) is usable]], [[mhd_cv_pipe2_usable]], [ + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ +AC_INCLUDES_DEFAULT +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + ], [[ + int arr[2]; + int res; + res = pipe2(arr, O_CLOEXEC | O_NONBLOCK) + ]]) + ], [[mhd_cv_pipe2_usable='yes']], [[mhd_cv_pipe2_usable='no']]) + ]) + AS_VAR_IF([[mhd_cv_pipe2_usable]], [["yes"]], + [AC_DEFINE([[HAVE_PIPE2_FUNC]], [[1]], [Define if you have usable pipe2(2) function])]) ], [ AS_VAR_IF([[enable_itc]], [["pipe"]], [AC_MSG_ERROR([[pipe(3) is not usable, consider using other type of inter-thread communication]])]) ]) diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c @@ -4466,17 +4466,6 @@ MHD_start_daemon_va (unsigned int flags, free (daemon); return NULL; } - if (! MHD_itc_nonblocking_ (daemon->itc)) - { -#ifdef HAVE_MESSAGES - MHD_DLOG (daemon, - _("Failed to make read side of inter-thread control channel non-blocking: %s\n"), - MHD_itc_last_strerror_ ()); -#endif - MHD_itc_destroy_chk_ (daemon->itc); - free (daemon); - return NULL; - } } if ( (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL))) && (1 == use_pipe) && @@ -4987,15 +4976,6 @@ MHD_start_daemon_va (unsigned int flags, #endif goto thread_failed; } - if (! MHD_itc_nonblocking_(d->itc)) - { -#ifdef HAVE_MESSAGES - MHD_DLOG (daemon, - _("Failed to make read side of worker inter-thread control channel non-blocking: %s\n"), - MHD_itc_last_strerror_ ()); -#endif - goto thread_failed; - } } if ( (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL))) && (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (daemon->itc), diff --git a/src/microhttpd/mhd_itc.c b/src/microhttpd/mhd_itc.c @@ -36,7 +36,7 @@ #if defined(_MHD_ITC_PIPE) #if !defined(_WIN32) || defined(__CYGWIN__) - +#ifndef HAVE_PIPE2_FUNC /** * Change itc FD options to be non-blocking. * @@ -65,5 +65,6 @@ MHD_itc_nonblocking_ (MHD_itc_ itc) } return !0; } +#endif /* ! HAVE_PIPE2_FUNC */ #endif /* !_WIN32 || __CYGWIN__ */ #endif /* _MHD_ITC_EVENTFD || _MHD_ITC_PIPE */ diff --git a/src/microhttpd/mhd_itc.h b/src/microhttpd/mhd_itc.h @@ -131,20 +131,14 @@ static const uint64_t _MHD_itc_wr_data = 1; */ #define MHD_itc_set_invalid_(itc) ((itc) = -1) -/** - * Change itc FD options to be non-blocking. As we already did this - * on eventfd creation, this always succeeds. - * - * @param fd the FD to manipulate - * @return non-zero if succeeded, zero otherwise - */ -#define MHD_itc_nonblocking_(pip) (!0) - #elif defined(_MHD_ITC_PIPE) /* **************** Standard UNIX ITC implementation by pipe ********** */ +#if defined(HAVE_PIPE2_FUNC) && defined(HAVE_FCNTL_H) +# include <fcntl.h> /* for O_CLOEXEC, O_NONBLOCK */ +#endif /* HAVE_PIPE2_FUNC && HAVE_FCNTL_H */ #ifdef HAVE_UNISTD_H #include <unistd.h> /* for read(), write(), errno */ #endif /* HAVE_UNISTD_H */ @@ -158,7 +152,16 @@ static const uint64_t _MHD_itc_wr_data = 1; * @param itc the itc to initialise * @return non-zero if succeeded, zero otherwise */ -#define MHD_itc_init_(itc) (!pipe((itc).fd)) +#ifdef HAVE_PIPE2_FUNC +# define MHD_itc_init_(itc) (!pipe2((itc).fd, O_CLOEXEC | O_NONBLOCK)) +#else /* ! HAVE_PIPE2_FUNC */ +# define MHD_itc_init_(itc) \ + ( (!pipe((itc).fd)) ? \ + (MHD_itc_nonblocking_((itc)) ? \ + (!0) : \ + (MHD_itc_destroy_((itc)), 0) ) \ + : (0) ) +#endif /* ! HAVE_PIPE2_FUNC */ /** * Get description string of last errno for itc operations. @@ -225,14 +228,16 @@ static const uint64_t _MHD_itc_wr_data = 1; */ #define MHD_itc_set_invalid_(itc) ((itc).fd[0] = (itc).fd[1] = -1) -/** - * Change itc FD options to be non-blocking. - * - * @param fd the FD to manipulate - * @return non-zero if succeeded, zero otherwise - */ -int -MHD_itc_nonblocking_ (MHD_itc_ itc); +#ifndef HAVE_PIPE2_FUNC + /** + * Change itc FD options to be non-blocking. + * + * @param fd the FD to manipulate + * @return non-zero if succeeded, zero otherwise + */ + int + MHD_itc_nonblocking_ (MHD_itc_ itc); +#endif /* ! HAVE_PIPE2_FUNC */ #elif defined(_MHD_ITC_SOCKETPAIR) @@ -247,7 +252,16 @@ MHD_itc_nonblocking_ (MHD_itc_ itc); * @param itc the itc to initialise * @return non-zero if succeeded, zero otherwise */ -#define MHD_itc_init_(itc) MHD_socket_pair_((itc).sk) +#ifdef MHD_socket_pair_nblk_ +# define MHD_itc_init_(itc) MHD_socket_pair_nblk_((itc).sk) +#else /* ! MHD_socket_pair_nblk_ */ +# define MHD_itc_init_(itc) \ + (MHD_socket_pair_((itc).sk) ? \ + (MHD_itc_nonblocking_((itc)) ? \ + (!0) : \ + (MHD_itc_destroy_((itc)), 0) ) \ + : (0)) +#endif /* ! MHD_socket_pair_nblk_ */ /** * Get description string of last error for itc operations. @@ -317,8 +331,9 @@ MHD_itc_nonblocking_ (MHD_itc_ itc); */ #define MHD_itc_set_invalid_(itc) ((itc).sk[0] = (itc).sk[1] = MHD_INVALID_SOCKET) - -#define MHD_itc_nonblocking_(pip) (MHD_socket_nonblocking_((pip).sk[0]) && MHD_socket_nonblocking_((pip).sk[1])) +#ifndef MHD_socket_pair_nblk_ +# define MHD_itc_nonblocking_(pip) (MHD_socket_nonblocking_((pip).sk[0]) && MHD_socket_nonblocking_((pip).sk[1])) +#endif /* ! MHD_socket_pair_nblk_ */ #endif /* _MHD_ITC_SOCKETPAIR */