瀏覽代碼

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

Evgeny Grin (Karlson2k) 9 年之前
父節點
當前提交
f5631e46aa
共有 4 個文件被更改,包括 57 次插入42 次删除
  1. 19 0
      configure.ac
  2. 0 20
      src/microhttpd/daemon.c
  3. 2 1
      src/microhttpd/mhd_itc.c
  4. 36 21
      src/microhttpd/mhd_itc.h

+ 19 - 0
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]])])
   ])

+ 0 - 20
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) &&
@@ -4984,15 +4973,6 @@ MHD_start_daemon_va (unsigned int flags,
                   MHD_DLOG (daemon,
                             _("Failed to create worker control pipe: %s\n"),
                             MHD_itc_last_strerror_() );
-#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;
                 }

+ 2 - 1
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 */

+ 36 - 21
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 */