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:
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 */