libmicrohttpd

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

commit 1e11762d5fabd80c70e226dd608fc6322de5ce61
parent dcebe56be139a0b4dbc4926c1d95e6dc4972ab67
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Thu, 21 Jan 2016 19:53:45 +0000

Reworked code for using accept4(), epoll_create1() and socket() with SOCK_CLOEXEC, SOCK_NONBLOCK and EPOLL_CLOEXEC. On some systems SOCK_CLOEXEC, SOCK_NONBLOCK and EPOLL_CLOEXEC are defined as enum members with the same names so precompiler assume zero value of such macros.

Diffstat:
MChangeLog | 8++++++++
Msrc/microhttpd/daemon.c | 45+++++++++++++++++++++++----------------------
2 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,11 @@ +Thu Jan 21 19:35:18 CET 2016 + Fixed old bug with making sockets non-blocking on + various platforms so now sockets are really + non-blocking on all supported platforms. + Reworked and fixed code for using SOCK_CLOEXEC, + SOCK_NONBLOCK and EPOLL_CLOEXEC resulting in + fewer used system calls. -EG + Tue Jan 19 20:59:59 CET 2016 Cleaned up and optimized with minor fixes code for making sockets non-blocking non-inheritable. -EG diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c @@ -103,18 +103,26 @@ #endif #endif -#ifndef SOCK_CLOEXEC -#define SOCK_CLOEXEC 0 -#endif +#ifdef SOCK_CLOEXEC +#define MAYBE_SOCK_CLOEXEC SOCK_CLOEXEC +#else /* ! SOCK_CLOEXEC */ +#define MAYBE_SOCK_CLOEXEC 0 +#endif /* ! SOCK_CLOEXEC */ -#ifndef EPOLL_CLOEXEC -#define EPOLL_CLOEXEC 0 -#endif +#ifdef HAVE_SOCK_NONBLOCK +#define MAYBE_SOCK_NONBLOCK SOCK_NONBLOCK +#else /* ! HAVE_SOCK_NONBLOCK */ +#define MAYBE_SOCK_NONBLOCK 0 +#endif /* ! HAVE_SOCK_NONBLOCK */ -#if HAVE_ACCEPT4+0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || (SOCK_CLOEXEC+0 != 0)) +#if HAVE_ACCEPT4+0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || defined(SOCK_CLOEXEC)) #define USE_ACCEPT4 1 #endif +#if defined(HAVE_EPOLL_CREATE1) && defined(EPOLL_CLOEXEC) +#define USE_EPOLL_CREATE1 1 +#endif /* HAVE_EPOLL_CREATE1 && EPOLL_CLOEXEC */ + /** * Default implementation of the panic function, @@ -1980,20 +1988,13 @@ MHD_accept_connection (struct MHD_Daemon *daemon) socklen_t addrlen; MHD_socket s; MHD_socket fd; -#ifdef USE_ACCEPT4 -#ifdef HAVE_SOCK_NONBLOCK - static const int nonblock = SOCK_NONBLOCK; -#else - static const int nonblock = 0; -#endif -#endif /* USE_ACCEPT4 */ addrlen = sizeof (addrstorage); memset (addr, 0, sizeof (addrstorage)); if (MHD_INVALID_SOCKET == (fd = daemon->socket_fd)) return MHD_NO; #ifdef USE_ACCEPT4 - s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC | nonblock); + s = accept4 (fd, addr, &addrlen, MAYBE_SOCK_CLOEXEC | MAYBE_SOCK_NONBLOCK); #else /* ! USE_ACCEPT4 */ s = accept (fd, addr, &addrlen); #endif /* ! USE_ACCEPT4 */ @@ -2022,7 +2023,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon) make_nonblocking_noninheritable (daemon, s); #elif !defined(HAVE_SOCK_NONBLOCK) make_nonblocking (daemon, s); -#elif SOCK_CLOEXEC+0 == 0 +#elif !defined(SOCK_CLOEXEC) make_noninheritable (daemon, s); #endif #ifdef HAVE_MESSAGES @@ -3564,7 +3565,7 @@ create_listen_socket (struct MHD_Daemon *daemon, /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo * implementations do not set ai_socktype, e.g. RHL6.2. */ -#if defined(MHD_POSIX_SOCKETS) && SOCK_CLOEXEC+0 != 0 +#if defined(MHD_POSIX_SOCKETS) && defined(SOCK_CLOEXEC) fd = socket (domain, type | SOCK_CLOEXEC, protocol); cloexec_set = MHD_YES; #elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT) @@ -3600,11 +3601,11 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon) { struct epoll_event event; -#ifdef HAVE_EPOLL_CREATE1 +#ifdef USE_EPOLL_CREATE1 daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC); -#else /* !HAVE_EPOLL_CREATE1 */ +#else /* ! USE_EPOLL_CREATE1 */ daemon->epoll_fd = epoll_create (MAX_EVENTS); -#endif /* !HAVE_EPOLL_CREATE1 */ +#endif /* ! USE_EPOLL_CREATE1 */ if (-1 == daemon->epoll_fd) { #ifdef HAVE_MESSAGES @@ -3614,10 +3615,10 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon) #endif return MHD_NO; } -#if !defined(HAVE_EPOLL_CREATE1) || EPOLL_CLOEXEC+0 == 0 +#if !defined(USE_EPOLL_CREATE1) make_noninheritable (daemon, daemon->epoll_fd); -#endif /* !HAVE_EPOLL_CREATE1 || !EPOLL_CLOEXEC */ +#endif /* ! USE_EPOLL_CREATE1 */ if (MHD_INVALID_SOCKET == daemon->socket_fd) return MHD_YES; /* non-listening daemon */ event.events = EPOLLIN;