gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [libmicrohttpd] 64/154: move sendfile function work to conn


From: gnunet
Subject: [GNUnet-SVN] [libmicrohttpd] 64/154: move sendfile function work to connection.c
Date: Mon, 19 Aug 2019 10:16:16 +0200

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to branch master
in repository libmicrohttpd.

commit 0c40dc481b3ed4149c9bb82118d5c923fb34dcde
Author: ng0 <address@hidden>
AuthorDate: Wed Jul 24 10:17:45 2019 +0000

    move sendfile function work to connection.c
---
 src/microhttpd/connection.c |  72 ++++++++++++
 src/microhttpd/mhd_send.c   | 262 +-------------------------------------------
 src/microhttpd/mhd_send.h   |   9 ++
 3 files changed, 82 insertions(+), 261 deletions(-)

diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 626adb42..3315ad22 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -288,6 +288,12 @@ send_param_adapter (struct MHD_Connection *connection,
 static ssize_t
 sendfile_adapter (struct MHD_Connection *connection)
 {
+  bool want_cork = false;
+  bool have_cork;
+  bool have_more;
+  bool use_corknopush;
+  bool using_tls = false;
+
   ssize_t ret;
   const int file_fd = connection->response->fd;
   uint64_t left;
@@ -454,6 +460,72 @@ sendfile_adapter (struct MHD_Connection *connection)
   mhd_assert (send_size >= (size_t)len);
   ret = (ssize_t)len;
 #endif /* HAVE_FREEBSD_SENDFILE */
+
+  /* ! could be avoided by redefining the variable. */
+  have_cork = ! connection->sk_tcp_nodelay_on;
+
+#ifdef MSG_MORE
+  have_more = true;
+#else
+  have_more = false;
+#endif
+
+#if TCP_NODELAY
+  use_corknopush = false;
+#elif TCP_CORK
+  use_corknopush = true;
+#elif TCP_NOPUSH
+  use_corknopush = true;
+#endif
+
+#ifdef HTTPS_SUPPORT
+  using_tls = (0 != (connection->daemon->options & MHD_USE_TLS));
+#endif
+
+#if TCP_CORK
+  /* When we have CORK, we can have NODELAY on the same system,
+   * at least since Linux 2.2 and both can be combined since
+   * Linux 2.5.71. For more details refer to tcp(7) on Linux.
+   * No other system in 2019-06 has TCP_CORK. */
+  if ((! using_tls) && (use_corknopush) && (have_cork && ! want_cork))
+    {
+      if (0 == setsockopt (connection->socket_fd,
+                           IPPROTO_TCP,
+                           TCP_CORK,
+                           (const void *) &off_val,
+                           sizeof (off_val)))
+      {
+        connection->sk_tcp_nodelay_on = true;
+      }
+      else if (0 == setsockopt (connection->socket_fd,
+                                IPPROTO_TCP,
+                                TCP_NODELAY,
+                                (const void *) &on_val,
+                                sizeof (on_val)))
+      {
+        connection->sk_tcp_nodelay_on = true;
+      }
+    }
+#elif TCP_NOPUSH
+  /* TCP_NOPUSH on FreeBSD is equal to cork on Linux, with the
+   * exception that we know that TCP_NOPUSH will definitely
+   * exist and we can disregard TCP_NODELAY unless requested. */
+  if ((! using_tls) && (use_corknopush) && (have_cork && ! want_cork))
+    {
+      MHD_send_socket_state_nopush_ (connection, true, false);
+      /*
+      if (0 == setsockopt (connection->socket_fd,
+                           IPPROTO_TCP,
+                           TCP_NOPUSH,
+                           (const void *) &on_val,
+                           sizeof (on_val)))
+        {
+          connection->sk_tcp_nodelay_on = false;
+        }
+      */
+    }
+#endif
+
   return ret;
 }
 #endif /* _MHD_HAVE_SENDFILE */
diff --git a/src/microhttpd/mhd_send.c b/src/microhttpd/mhd_send.c
index 7e312b59..1d3b739a 100644
--- a/src/microhttpd/mhd_send.c
+++ b/src/microhttpd/mhd_send.c
@@ -24,14 +24,13 @@
  * @author ng0 <address@hidden>
  */
 
-/* TODO: sendfile() wrappers. */
+/* TODO: sendfile() wrapper, in connection.c */
 
 /* Functions to be used in: send_param_adapter, MHD_send_
  * and every place where sendfile(), sendfile64(), setsockopt()
  * are used. */
 
 #include "mhd_send.h"
-#include "connection.h"
 
 /**
  * Set socket to nodelay, on or off.
@@ -496,262 +495,3 @@ MHD_send_on_connection2_ (struct MHD_Connection 
*connection,
  * with this seems to be to mmap the file and write(2) as
  * large a chunk as possible to the socket. Alternatively,
  * use madvise(..., MADV_SEQUENTIAL). */
-
-#if defined(_MHD_HAVE_SENDFILE)
-/**
- * Function for sending responses backed by file FD.
- * A sendfile() wrapper which also performs cork/uncork
- * operations.
- *
- * @param connection the #MHD_Connection structure
- * @return actual number of bytes sent
- */
-ssize_t
-MHD_sendfile_on_connection_ (struct MHD_Connection *connection)
-{
-  // I'm looking for a version of sendfile_adapter() that *also* performs
-  // cork/uncork operations. Specifically, we want to make sure that the
-  // buffer is flushed after sendfile() is done (so setsockopt() behavior
-  // equivalent to MHD_SSO_NO_CORK), and _also_ of course update the
-  // setsockopt state, i.e. connection->sk_tcp_nodelay_on = true;
-
-  bool want_cork = false;
-  bool have_cork;
-  bool have_more;
-  bool use_corknopush;
-  bool using_tls = false;
-  ssize_t ret;
-  const int file_fd = connection->response->fd;
-  uint64_t left;
-  uint64_t offsetu64;
-#ifndef HAVE_SENDFILE64
-  const uint64_t max_off_t = (uint64_t)OFF_T_MAX;
-#else  /* HAVE_SENDFILE64 */
-  const uint64_t max_off_t = (uint64_t)OFF64_T_MAX;
-#endif /* HAVE_SENDFILE64 */
-#ifdef MHD_LINUX_SOLARIS_SENDFILE
-#ifndef HAVE_SENDFILE64
-  off_t offset;
-#else  /* HAVE_SENDFILE64 */
-  off64_t offset;
-#endif /* HAVE_SENDFILE64 */
-#endif /* MHD_LINUX_SOLARIS_SENDFILE */
-#ifdef HAVE_FREEBSD_SENDFILE
-  off_t sent_bytes;
-  int flags = 0;
-#endif
-#ifdef HAVE_DARWIN_SENDFILE
-  off_t len;
-#endif /* HAVE_DARWIN_SENDFILE */
-  const bool used_thr_p_c = (0 != (connection->daemon->options & 
MHD_USE_THREAD_PER_CONNECTION));
-  const size_t chunk_size = used_thr_p_c ? MHD_SENFILE_CHUNK_THR_P_C_ : 
MHD_SENFILE_CHUNK_;
-  size_t send_size = 0;
-  mhd_assert (MHD_resp_sender_sendfile == connection->resp_sender);
-
-  offsetu64 = connection->response_write_position + 
connection->response->fd_off;
-  left = connection->response->total_size - 
connection->response_write_position;
-  /* Do not allow system to stick sending on single fast connection:
-   * use 128KiB chunks (2MiB for thread-per-connection). */
-  send_size = (left > chunk_size) ? chunk_size : (size_t) left;
-  if (max_off_t < offsetu64)
-    { /* Retry to send with standard 'send()'. */
-      connection->resp_sender = MHD_resp_sender_std;
-      return MHD_ERR_AGAIN_;
-    }
-#ifdef MHD_LINUX_SOLARIS_SENDFILE
-#ifndef HAVE_SENDFILE64
-  offset = (off_t) offsetu64;
-  ret = sendfile (connection->socket_fd,
-                  file_fd,
-                  &offset,
-                  send_size);
-#else  /* HAVE_SENDFILE64 */
-  offset = (off64_t) offsetu64;
-  ret = sendfile64 (connection->socket_fd,
-                    file_fd,
-                    &offset,
-                    send_size);
-#endif /* HAVE_SENDFILE64 */
-  if (0 > ret)
-    {
-      const int err = MHD_socket_get_error_();
-      if (MHD_SCKT_ERR_IS_EAGAIN_(err))
-        {
-#ifdef EPOLL_SUPPORT
-          /* EAGAIN --- no longer write-ready */
-          connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
-#endif /* EPOLL_SUPPORT */
-          return MHD_ERR_AGAIN_;
-        }
-      if (MHD_SCKT_ERR_IS_EINTR_ (err))
-        return MHD_ERR_AGAIN_;
-#ifdef HAVE_LINUX_SENDFILE
-      if (MHD_SCKT_ERR_IS_(err,
-                           MHD_SCKT_EBADF_))
-        return MHD_ERR_BADF_;
-      /* sendfile() failed with EINVAL if mmap()-like operations are not
-         supported for FD or other 'unusual' errors occurred, so we should try
-         to fall back to 'SEND'; see also this thread for info on
-         odd libc/Linux behavior with sendfile:
-         http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html 
*/
-      connection->resp_sender = MHD_resp_sender_std;
-      return MHD_ERR_AGAIN_;
-#else  /* HAVE_SOLARIS_SENDFILE */
-      if ( (EAFNOSUPPORT == err) ||
-           (EINVAL == err) ||
-           (EOPNOTSUPP == err) )
-        { /* Retry with standard file reader. */
-          connection->resp_sender = MHD_resp_sender_std;
-          return MHD_ERR_AGAIN_;
-        }
-      if ( (ENOTCONN == err) ||
-           (EPIPE == err) )
-        {
-          return MHD_ERR_CONNRESET_;
-        }
-      return MHD_ERR_BADF_; /* Fail hard */
-#endif /* HAVE_SOLARIS_SENDFILE */
-    }
-#ifdef EPOLL_SUPPORT
-  else if (send_size > (size_t)ret)
-        connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
-#endif /* EPOLL_SUPPORT */
-#elif defined(HAVE_FREEBSD_SENDFILE)
-#ifdef SF_FLAGS
-  flags = used_thr_p_c ?
-      freebsd_sendfile_flags_thd_p_c_ : freebsd_sendfile_flags_;
-#endif /* SF_FLAGS */
-  if (0 != sendfile (file_fd,
-                     connection->socket_fd,
-                     (off_t) offsetu64,
-                     send_size,
-                     NULL,
-                     &sent_bytes,
-                     flags))
-    {
-      const int err = MHD_socket_get_error_();
-      if (MHD_SCKT_ERR_IS_EAGAIN_(err) ||
-          MHD_SCKT_ERR_IS_EINTR_(err) ||
-          EBUSY == err)
-        {
-          mhd_assert (SSIZE_MAX >= sent_bytes);
-          if (0 != sent_bytes)
-            return (ssize_t)sent_bytes;
-
-          return MHD_ERR_AGAIN_;
-        }
-      /* Some unrecoverable error. Possibly file FD is not suitable
-       * for sendfile(). Retry with standard send(). */
-      connection->resp_sender = MHD_resp_sender_std;
-      return MHD_ERR_AGAIN_;
-    }
-  mhd_assert (0 < sent_bytes);
-  mhd_assert (SSIZE_MAX >= sent_bytes);
-  ret = (ssize_t)sent_bytes;
-#elif defined(HAVE_DARWIN_SENDFILE)
-  len = (off_t)send_size; /* chunk always fit */
-  if (0 != sendfile (file_fd,
-                     connection->socket_fd,
-                     (off_t) offsetu64,
-                     &len,
-                     NULL,
-                     0))
-    {
-      const int err = MHD_socket_get_error_();
-      if (MHD_SCKT_ERR_IS_EAGAIN_(err) ||
-          MHD_SCKT_ERR_IS_EINTR_(err))
-        {
-          mhd_assert (0 <= len);
-          mhd_assert (SSIZE_MAX >= len);
-          mhd_assert (send_size >= (size_t)len);
-          if (0 != len)
-            return (ssize_t)len;
-
-          return MHD_ERR_AGAIN_;
-        }
-      if (ENOTCONN == err ||
-          EPIPE == err)
-        return MHD_ERR_CONNRESET_;
-      if (ENOTSUP == err ||
-          EOPNOTSUPP == err)
-        { /* This file FD is not suitable for sendfile().
-           * Retry with standard send(). */
-          connection->resp_sender = MHD_resp_sender_std;
-          return MHD_ERR_AGAIN_;
-        }
-      return MHD_ERR_BADF_; /* Return hard error. */
-    }
-  mhd_assert (0 <= len);
-  mhd_assert (SSIZE_MAX >= len);
-  mhd_assert (send_size >= (size_t)len);
-  ret = (ssize_t)len;
-#endif /* HAVE_FREEBSD_SENDFILE */
-
-  /* ! could be avoided by redefining the variable. */
-  have_cork = ! connection->sk_tcp_nodelay_on;
-
-#ifdef MSG_MORE
-  have_more = true;
-#else
-  have_more = false;
-#endif
-
-#if TCP_NODELAY
-  use_corknopush = false;
-#elif TCP_CORK
-  use_corknopush = true;
-#elif TCP_NOPUSH
-  use_corknopush = true;
-#endif
-
-#ifdef HTTPS_SUPPORT
-  using_tls = (0 != (connection->daemon->options & MHD_USE_TLS));
-#endif
-
-#if TCP_CORK
-  /* When we have CORK, we can have NODELAY on the same system,
-   * at least since Linux 2.2 and both can be combined since
-   * Linux 2.5.71. For more details refer to tcp(7) on Linux.
-   * No other system in 2019-06 has TCP_CORK. */
-  if ((! using_tls) && (use_corknopush) && (have_cork && ! want_cork))
-    {
-      if (0 == setsockopt (connection->socket_fd,
-                           IPPROTO_TCP,
-                           TCP_CORK,
-                           (const void *) &off_val,
-                           sizeof (off_val)))
-      {
-        connection->sk_tcp_nodelay_on = true;
-      }
-      else if (0 == setsockopt (connection->socket_fd,
-                                IPPROTO_TCP,
-                                TCP_NODELAY,
-                                (const void *) &on_val,
-                                sizeof (on_val)))
-      {
-        connection->sk_tcp_nodelay_on = true;
-      }
-    }
-#elif TCP_NOPUSH
-  /* TCP_NOPUSH on FreeBSD is equal to cork on Linux, with the
-   * exception that we know that TCP_NOPUSH will definitely
-   * exist and we can disregard TCP_NODELAY unless requested. */
-  if ((! using_tls) && (use_corknopush) && (have_cork && ! want_cork))
-    {
-      MHD_send_socket_state_nopush_ (connection, true, false);
-      /*
-      if (0 == setsockopt (connection->socket_fd,
-                           IPPROTO_TCP,
-                           TCP_NOPUSH,
-                           (const void *) &on_val,
-                           sizeof (on_val)))
-        {
-          connection->sk_tcp_nodelay_on = false;
-        }
-      */
-    }
-#endif
-
-  return ret;
-}
-#endif /* _MHD_HAVE_SENDFILE */
diff --git a/src/microhttpd/mhd_send.h b/src/microhttpd/mhd_send.h
index a6049865..c4a6d705 100644
--- a/src/microhttpd/mhd_send.h
+++ b/src/microhttpd/mhd_send.h
@@ -77,4 +77,13 @@ MHD_send_on_connection2_ (struct MHD_Connection *connection,
 
 ssize_t
 MHD_sendfile_on_connection_ (struct MHD_Connection *connection);
+
+void
+MHD_send_socket_state_nopush_ (struct MHD_Connection *connection,
+                               bool value,
+                               bool state_store);
+
+void
+MHD_send_socket_state_nodelay_ (struct MHD_Connection *connection,
+                                bool value);
 #endif /* MHD_SEND_H */

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]