libmicrohttpd

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

commit 53e25ec3e4ad1701c83f035fc8ea6d3ac42696dc
parent 3add309d9812e9f964c1434ab34ce90f6f8919e1
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu, 22 Sep 2016 15:51:57 +0000

implement #3557

Diffstat:
MChangeLog | 4++++
Mconfigure.ac | 2+-
Msrc/microhttpd/mhd_itc.c | 22+++++++++++++++++++++-
Msrc/microhttpd/mhd_itc.h | 90++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
4 files changed, 111 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,7 @@ +Thu Sep 22 17:51:04 CEST 2016 + Implementing support for eventfd() instead of pipe() for + signaling (on platforms that support it); fixing #3557. -CG + Thu Sep 22 11:03:43 CEST 2016 Simplify internal error handling logic by folding it into the MHD_socket_close_, MHD_mutex_lock_, MHD_mutex_unlock_ and diff --git a/configure.ac b/configure.ac @@ -562,7 +562,7 @@ AC_CHECK_HEADERS([sys/types.h sys/time.h sys/msg.h time.h sys/mman.h search.h sy sys/socket.h sys/select.h netdb.h netinet/in.h netinet/ip.h netinet/tcp.h arpa/inet.h \ endian.h machine/endian.h sys/endian.h sys/param.h sys/machine.h sys/byteorder.h machine/param.h sys/isa_defs.h \ inttypes.h stddef.h unistd.h \ - sockLib.h inetLib.h net/if.h]) + sockLib.h inetLib.h net/if.h sys/eventfd.h]) AM_CONDITIONAL([HAVE_TSEARCH], [test "x$ac_cv_header_search_h" = "xyes"]) # Check for generic functions diff --git a/src/microhttpd/mhd_itc.c b/src/microhttpd/mhd_itc.c @@ -25,11 +25,30 @@ */ #include "mhd_itc.h" - #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ #include <fcntl.h> +#include "internal.h" + + +#ifdef HAVE_SYS_EVENTFD_H + +int +MHD_pipe_write_ (struct MHD_Pipe pip, + const void *ptr, + size_t sz) +{ + uint64_t val = 1; + if (sizeof (val) != + write (pip.event_fd, + &val, + sizeof (val))) + MHD_PANIC (_("Failed to write to eventfd\n")); + return sz; +} + +#else #ifndef MHD_DONT_USE_PIPES #if !defined(_WIN32) || defined(__CYGWIN__) @@ -65,3 +84,4 @@ MHD_itc_nonblocking_ (struct MHD_Pipe pip) } #endif /* _WIN32 && ! __CYGWIN__ */ #endif /* ! MHD_DONT_USE_PIPES */ +#endif /* ! HAVE_SYS_EVENTFD_H */ diff --git a/src/microhttpd/mhd_itc.h b/src/microhttpd/mhd_itc.h @@ -19,9 +19,10 @@ */ /** - * @file microhttpd/mhd_sockets.c - * @brief Header for platform-independent inter-thread communication + * @file microhttpd/mhd_itc.h + * @brief Header for platform-independent inter-thread signaling via pipes * @author Karlson2k (Evgeny Grin) + * @author Christian Grothoff * * Provides basic abstraction for inter-thread communication. * Any functions can be implemented as macro on some platforms @@ -29,17 +30,95 @@ * Any function argument can be skipped in macro, so avoid * variable modification in function parameters. */ - #ifndef MHD_ITC_H #define MHD_ITC_H 1 #include "mhd_options.h" +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#include <fcntl.h> + +#ifdef HAVE_SYS_EVENTFD_H + +#include <sys/eventfd.h> +/* **************** Optimized eventfd PIPE implementation ********** */ + +/** + * Data type for a MHD pipe. + */ +struct MHD_Pipe +{ + int event_fd; +}; + +/** + * create pipe + */ +#define MHD_pipe_(pip) ((-1 == (pip.event_fd = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK))) ? 0 : !0) + +/*** + * Get description string of last errno for pipe operations. + */ +#define MHD_pipe_last_strerror_() strerror(errno) + +/** + * write data to real pipe + */ +int +MHD_pipe_write_ (struct MHD_Pipe pip, + const void *ptr, + size_t sz); + +#define MHD_pipe_get_read_fd_(pip) (pip.event_fd) + +#define MHD_pipe_get_write_fd_(pip) (pip.event_fd) + +/** + * drain data from real pipe + */ +#define MHD_pipe_drain_(pip) do { \ + uint64_t tmp; \ + read (pip.event_fd, &tmp, sizeof (tmp)); \ + } while (0) + +/** + * Close any FDs of the pipe (non-W32) + */ +#define MHD_pipe_close_(pip) do { \ + close (pip.event_fd); \ + } while (0) + +/** + * Check if we have an uninitialized pipe + */ +#define MHD_INVALID_PIPE_(pip) (-1 == pip.event_fd) + +/** + * Setup uninitialized @a pip data structure. + */ +#define MHD_make_invalid_pipe_(pip) do { \ + pip.event_fd = -1; \ + } while (0) + + +/** + * 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) + + +#else + /* Force don't use pipes on W32 */ #if defined(_WIN32) && !defined(MHD_DONT_USE_PIPES) #define MHD_DONT_USE_PIPES 1 #endif /* defined(_WIN32) && !defined(MHD_DONT_USE_PIPES) */ - #ifndef MHD_DONT_USE_PIPES /* **************** STANDARD UNIX PIPE implementation ********** */ @@ -71,6 +150,7 @@ struct MHD_Pipe */ #define MHD_pipe_write_(pip, ptr, sz) write((pip.fd[1]), (const void*)(ptr), (sz)) + #define MHD_pipe_get_read_fd_(pip) (pip.fd[0]) #define MHD_pipe_get_write_fd_(pip) (pip.fd[1]) @@ -182,6 +262,6 @@ struct MHD_Pipe #endif /* MHD_DONT_USE_PIPES */ - +#endif /* HAVE_SYS_EVENTFD_H */ #endif /* MHD_ITC_H */