[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r36849 - in libmicrohttpd: . src/microhttpd
From: |
gnunet |
Subject: |
[GNUnet-SVN] r36849 - in libmicrohttpd: . src/microhttpd |
Date: |
Tue, 19 Jan 2016 22:18:25 +0100 |
Author: Karlson2k
Date: 2016-01-19 22:18:25 +0100 (Tue, 19 Jan 2016)
New Revision: 36849
Modified:
libmicrohttpd/ChangeLog
libmicrohttpd/src/microhttpd/daemon.c
Log:
daemon.c: refactored code making sockets non-blocking and non-inheritable:
cleaned up, clarified and little bit optimized.
Modified: libmicrohttpd/ChangeLog
===================================================================
--- libmicrohttpd/ChangeLog 2016-01-19 16:55:18 UTC (rev 36848)
+++ libmicrohttpd/ChangeLog 2016-01-19 21:18:25 UTC (rev 36849)
@@ -1,3 +1,7 @@
+Tue Jan 19 20:59:59 CET 2016
+ Cleaned up and optimized with minor fixes code for
+ making sockets non-blocking non-inheritable. -EG
+
Tue Jan 19 11:14:18 CET 2016
Removed workaround for Cygwin non-blocking sockets:
handling non-blocking sockets were fixed in Cygwin
Modified: libmicrohttpd/src/microhttpd/daemon.c
===================================================================
--- libmicrohttpd/src/microhttpd/daemon.c 2016-01-19 16:55:18 UTC (rev
36848)
+++ libmicrohttpd/src/microhttpd/daemon.c 2016-01-19 21:18:25 UTC (rev
36849)
@@ -64,10 +64,6 @@
#include <process.h>
#endif
-#if HAVE_ACCEPT4+0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || (SOCK_CLOEXEC+0 !=
0))
-#define USE_ACCEPT4 1
-#endif
-
/**
* Default connection limit.
*/
@@ -115,7 +111,11 @@
#define EPOLL_CLOEXEC 0
#endif
+#if HAVE_ACCEPT4+0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || (SOCK_CLOEXEC+0 !=
0))
+#define USE_ACCEPT4 1
+#endif
+
/**
* Default implementation of the panic function,
* prints an error message and aborts.
@@ -157,7 +157,51 @@
static int mhd_winsock_inited_ = 0;
#endif
+
/**
+ * Change socket options to be non-blocking.
+ *
+ * @param daemon daemon context
+ * @param sock socket to manipulate
+ * @return #MHD_YES if succeeded, #MHD_NO otherwise
+ */
+static int
+make_nonblocking (struct MHD_Daemon *daemon,
+ MHD_socket sock)
+{
+#ifdef MHD_WINSOCK_SOCKETS
+ unsigned long flags = 1;
+
+ if (0 != ioctlsocket (sock, FIONBIO, &flags))
+ {
+ #ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ "Failed to make socket non-blocking: %s\n",
+ MHD_socket_last_strerr_ ());
+ #endif
+ return MHD_NO;
+ }
+#else /* MHD_POSIX_SOCKETS */
+ int flags;
+
+ flags = fcntl (sock, F_GETFD);
+ if ( ( (-1 == flags) ||
+ ( (flags != (flags | O_NONBLOCK)) &&
+ (0 != fcntl (sock, F_SETFD, flags | O_NONBLOCK)) ) ) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ "Failed to make socket non-blocking: %s\n",
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_NO;
+ }
+#endif /* MHD_POSIX_SOCKETS */
+ return MHD_YES;
+}
+
+
+/**
* Trace up to and return master daemon. If the supplied daemon
* is a master, then return the daemon itself.
*
@@ -1462,30 +1506,7 @@
{
/* in turbo mode, we assume that non-blocking was already set
by 'accept4' or whoever calls 'MHD_add_connection' */
-
- /* make socket non-blocking */
-#if !defined(MHD_WINSOCK_SOCKETS)
- int flags = fcntl (connection->socket_fd, F_GETFL);
- if ( (-1 == flags) ||
- (0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) )
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- "Failed to make socket non-blocking: %s\n",
- MHD_socket_last_strerr_ ());
-#endif
- }
-#else
- unsigned long flags = 1;
- if (0 != ioctlsocket (connection->socket_fd, FIONBIO, &flags))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- "Failed to make socket non-blocking: %s\n",
- MHD_socket_last_strerr_ ());
-#endif
- }
-#endif
+ make_nonblocking (daemon, connection->socket_fd);
}
#if HTTPS_SUPPORT
@@ -1833,34 +1854,59 @@
/**
- * Change socket options to be non-blocking, non-inheritable.
+ * Change socket options to be non-inheritable.
*
* @param daemon daemon context
* @param sock socket to manipulate
+ * @return #MHD_YES if succeeded, #MHD_NO otherwise
*/
-static void
-make_nonblocking_noninheritable (struct MHD_Daemon *daemon,
- MHD_socket sock)
+static int
+make_noninheritable (struct MHD_Daemon *daemon,
+ MHD_socket sock)
{
#ifdef MHD_WINSOCK_SOCKETS
- unsigned long flags = 1;
-
- if (0 != ioctlsocket (sock, FIONBIO, &flags))
+ if (!SetHandleInformation ((HANDLE)sock, HANDLE_FLAG_INHERIT, 0))
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
- "Failed to make socket non-blocking: %s\n",
- MHD_socket_last_strerr_ ());
+ "Failed to make socket non-inheritable: %u\n",
+ (unsigned int)GetLastError ());
#endif
+ return MHD_NO;
}
- if (!SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, 0))
+#else /* MHD_POSIX_SOCKETS */
+ int flags;
+
+ flags = fcntl (sock, F_GETFD);
+ if ( ( (-1 == flags) ||
+ ( (flags != (flags | FD_CLOEXEC)) &&
+ (0 != fcntl (sock, F_SETFD, flags | FD_CLOEXEC)) ) ) )
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
- "Failed to make socket non-inheritable: %u\n",
- (unsigned int) GetLastError ());
+ "Failed to make socket non-inheritable: %s\n",
+ MHD_socket_last_strerr_ ());
#endif
+ return MHD_NO;
}
+#endif /* MHD_POSIX_SOCKETS */
+ return MHD_YES;
+}
+
+
+/**
+ * Change socket options to be non-blocking, non-inheritable.
+ *
+ * @param daemon daemon context
+ * @param sock socket to manipulate
+ */
+static void
+make_nonblocking_noninheritable (struct MHD_Daemon *daemon,
+ MHD_socket sock)
+{
+#ifdef MHD_WINSOCK_SOCKETS
+ (void)make_nonblocking (daemon, sock);
+ (void)make_noninheritable (daemon, sock);
#else
int flags;
@@ -1914,8 +1960,11 @@
const struct sockaddr *addr,
socklen_t addrlen)
{
- make_nonblocking_noninheritable (daemon,
- client_socket);
+ /* internal_add_connection() assume that non-blocking is
+ already set in MHD_USE_EPOLL_TURBO mode */
+ if (0 != (daemon->options & MHD_USE_EPOLL_TURBO))
+ make_nonblocking_noninheritable (daemon,
+ client_socket);
return internal_add_connection (daemon,
client_socket,
addr, addrlen,
@@ -1985,8 +2034,12 @@
}
return MHD_NO;
}
-#if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) || SOCK_CLOEXEC+0 == 0
+#if !defined(USE_ACCEPT4)
make_nonblocking_noninheritable (daemon, s);
+#elif !defined(HAVE_SOCK_NONBLOCK)
+ make_nonblocking (daemon, s);
+#elif SOCK_CLOEXEC+0 == 0
+ make_noninheritable (daemon, s);
#endif
#ifdef HAVE_MESSAGES
#if DEBUG_CONNECT
@@ -3519,24 +3572,33 @@
* @param protocol desired protocol, 0 for default
*/
static MHD_socket
-create_socket (struct MHD_Daemon *daemon,
- int domain, int type, int protocol)
+create_listen_socket (struct MHD_Daemon *daemon,
+ int domain, int type, int protocol)
{
- int ctype = type | SOCK_CLOEXEC;
MHD_socket fd;
+ int cloexec_set;
/* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
* implementations do not set ai_socktype, e.g. RHL6.2. */
- fd = socket (domain, ctype, protocol);
- if ( (MHD_INVALID_SOCKET == fd) && (EINVAL == MHD_socket_errno_) && (0 !=
SOCK_CLOEXEC) )
- {
- ctype = type;
- fd = socket(domain, type, protocol);
- }
+#if defined(MHD_POSIX_SOCKETS) && SOCK_CLOEXEC+0 != 0
+ fd = socket (domain, type | SOCK_CLOEXEC, protocol);
+ cloexec_set = MHD_YES;
+#elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT)
+ fd = WSASocketW (domain, type, protocol, NULL, 0,
WSA_FLAG_NO_HANDLE_INHERIT);
+ cloexec_set = MHD_YES;
+#else /* !SOCK_CLOEXEC */
+ fd = socket (domain, type, protocol);
+ cloexec_set = MHD_NO;
+#endif /* !SOCK_CLOEXEC */
+ if ( (MHD_INVALID_SOCKET == fd) && (MHD_NO != cloexec_set) )
+ {
+ fd = socket (domain, type, protocol);
+ cloexec_set = MHD_NO;
+ }
if (MHD_INVALID_SOCKET == fd)
return MHD_INVALID_SOCKET;
- if (type == ctype)
- make_nonblocking_noninheritable (daemon, fd);
+ if (MHD_NO == cloexec_set)
+ make_noninheritable (daemon, fd);
return fd;
}
@@ -3568,23 +3630,10 @@
#endif
return MHD_NO;
}
-#ifndef HAVE_EPOLL_CREATE1
- else
- {
- int fdflags = fcntl (daemon->epoll_fd, F_GETFD);
- if (0 > fdflags || 0 > fcntl (daemon->epoll_fd, F_SETFD, fdflags |
FD_CLOEXEC))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- "Failed to change flags on epoll fd: %s\n",
- MHD_socket_last_strerr_ ());
-#endif /* HAVE_MESSAGES */
- }
- }
-#endif /* !HAVE_EPOLL_CREATE1 */
- if (0 == EPOLL_CLOEXEC)
- make_nonblocking_noninheritable (daemon,
- daemon->epoll_fd);
+#if !defined(HAVE_EPOLL_CREATE1) || EPOLL_CLOEXEC+0 == 0
+ make_noninheritable (daemon,
+ daemon->epoll_fd);
+#endif /* !HAVE_EPOLL_CREATE1 || !EPOLL_CLOEXEC */
if (MHD_INVALID_SOCKET == daemon->socket_fd)
return MHD_YES; /* non-listening daemon */
event.events = EPOLLIN;
@@ -3870,10 +3919,10 @@
{
/* try to open listen socket */
if (0 != (flags & MHD_USE_IPv6))
- socket_fd = create_socket (daemon,
+ socket_fd = create_listen_socket (daemon,
PF_INET6, SOCK_STREAM, 0);
else
- socket_fd = create_socket (daemon,
+ socket_fd = create_listen_socket (daemon,
PF_INET, SOCK_STREAM, 0);
if (MHD_INVALID_SOCKET == socket_fd)
{
@@ -4073,23 +4122,24 @@
}
}
#endif
-#if EPOLL_SUPPORT
- if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY))
- {
- int sk_flags = fcntl (socket_fd, F_GETFL);
- if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
- {
+ if (MHD_NO == make_nonblocking (daemon, socket_fd))
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- "Failed to make listen socket non-blocking: %s\n",
- MHD_socket_last_strerr_ ());
-#endif
- if (0 != MHD_socket_close_ (socket_fd))
- MHD_PANIC ("close failed\n");
- goto free_and_fail;
- }
- }
-#endif
+ MHD_DLOG (daemon,
+ "Failed to make listen socket non-blocking: %s\n",
+ MHD_socket_last_strerr_ ());
+#endif /* HAVE_MESSAGES */
+ if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY) ||
+ daemon->worker_pool_size > 0)
+ {
+ /* Accept must be non-blocking. Multiple children may wake up
+ * to handle a new connection, but only one will win the race.
+ * The others must immediately return. */
+ if (0 != MHD_socket_close_ (socket_fd))
+ MHD_PANIC ("close failed\n");
+ goto free_and_fail;
+ }
+ }
if (listen (socket_fd, daemon->listen_backlog_size) < 0)
{
#ifdef HAVE_MESSAGES
@@ -4211,12 +4261,6 @@
if ( (daemon->worker_pool_size > 0) &&
(0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
{
-#if !defined(MHD_WINSOCK_SOCKETS)
- int sk_flags;
-#else
- unsigned long sk_flags;
-#endif
-
/* Coarse-grained count of connections per thread (note error
* due to integer division). Also keep track of how many
* connections are leftover after an equal split. */
@@ -4227,21 +4271,6 @@
i = 0; /* we need this in case fcntl or malloc fails */
- /* Accept must be non-blocking. Multiple children may wake up
- * to handle a new connection, but only one will win the race.
- * The others must immediately return. */
-#if !defined(MHD_WINSOCK_SOCKETS)
- sk_flags = fcntl (socket_fd, F_GETFL);
- if (sk_flags < 0)
- goto thread_failed;
- if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
- goto thread_failed;
-#else
- sk_flags = 1;
- if (SOCKET_ERROR == ioctlsocket (socket_fd, FIONBIO, &sk_flags))
- goto thread_failed;
-#endif /* MHD_WINSOCK_SOCKETS */
-
/* Allocate memory for pooled objects */
daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
* daemon->worker_pool_size);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r36849 - in libmicrohttpd: . src/microhttpd,
gnunet <=