[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [libmicrohttpd] 04/05: Added support for Darwin-style sendf
From: |
gnunet |
Subject: |
[GNUnet-SVN] [libmicrohttpd] 04/05: Added support for Darwin-style sendfile() |
Date: |
Wed, 22 Nov 2017 12:46:38 +0100 |
This is an automated email from the git hooks/post-receive script.
karlson2k pushed a commit to branch master
in repository libmicrohttpd.
commit e28049cccb0d25cf5d93436c7db431f4d147ac59
Author: Evgeny Grin (Karlson2k) <address@hidden>
AuthorDate: Wed Nov 22 14:12:55 2017 +0300
Added support for Darwin-style sendfile()
---
configure.ac | 40 +++++++++++++++++++++++++++++
src/include/mhd_options.h | 6 +++++
src/microhttpd/connection.c | 62 +++++++++++++++++++++++++++++++++++++--------
src/microhttpd/internal.h | 4 +--
4 files changed, 99 insertions(+), 13 deletions(-)
diff --git a/configure.ac b/configure.ac
index ca336ab7..625b74ab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1311,6 +1311,46 @@ int sendfile(int, int, off_t, size_t,
)
]
)
+AS_VAR_IF([[found_sendfile]], [["no"]],
+ [
+ AC_MSG_CHECKING([[for Darwin-style sendfile(2)]])
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+static void empty_func(void)
+{
+/* Check for declaration */
+ (void)sendfile;
+}
+/* Declare again to check form match */
+int sendfile(int, int, off_t, off_t*,
+ struct sf_hdtr *, int);
+ ]],
+ [[
+ int fd=0, s=1;
+ off_t o = 0;
+ off_t l = 5;
+ int r;
+ r = sendfile (fd, s, o, &l, (void*)0, 0);
+ if (r)
+ empty_func();
+ ]]
+ )
+ ],
+ [
+ AC_DEFINE([HAVE_DARWIN_SENDFILE], [1], [Define to 1 if you have
Darwin-style sendfile(2).])
+ found_sendfile="yes, Darwin-style"
+ AC_MSG_RESULT([[yes]])
+ ],
+ [AC_MSG_RESULT([[no]])
+ ]
+ )
+ ]
+)
AS_VAR_IF([[found_sendfile]], [["no"]],
[
diff --git a/src/include/mhd_options.h b/src/include/mhd_options.h
index d009630e..25b5cd52 100644
--- a/src/include/mhd_options.h
+++ b/src/include/mhd_options.h
@@ -65,6 +65,12 @@
#define _MHD_FD_SETSIZE_IS_DEFAULT 1
#endif /* !FD_SETSIZE && !WinSock*/
+#if defined(HAVE_LINUX_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE) || \
+ defined(HAVE_DARWIN_SENDFILE) || defined(HAVE_SOLARIS_SENDFILE)
+/* Have any supported sendfile() function. */
+#define _MHD_HAVE_SENDFILE
+#endif /* HAVE_LINUX_SENDFILE || HAVE_FREEBSD_SENDFILE ||
+ HAVE_DARWIN_SENDFILE || HAVE_SOLARIS_SENDFILE */
#if defined(HAVE_LINUX_SENDFILE) || defined(HAVE_SOLARIS_SENDFILE)
#define MHD_LINUX_SOLARIS_SENDFILE 1
#endif /* HAVE_LINUX_SENDFILE || HAVE_SOLARIS_SENDFILE */
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 623b40a5..ef61fdb6 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -39,11 +39,11 @@
#ifdef MHD_LINUX_SOLARIS_SENDFILE
#include <sys/sendfile.h>
#endif /* MHD_LINUX_SOLARIS_SENDFILE */
-#ifdef HAVE_FREEBSD_SENDFILE
+#if defined(HAVE_FREEBSD_SENDFILE) || defined(HAVE_DARWIN_SENDFILE)
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
-#endif /* HAVE_FREEBSD_SENDFILE */
+#endif /* HAVE_FREEBSD_SENDFILE || HAVE_DARWIN_SENDFILE */
#ifdef HTTPS_SUPPORT
#include "connection_https.h"
#endif /* HTTPS_SUPPORT */
@@ -272,7 +272,7 @@ send_param_adapter (struct MHD_Connection *connection,
}
-#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE)
+#if defined(_MHD_HAVE_SENDFILE)
/**
* Function for sending responses backed by file FD.
*
@@ -302,6 +302,9 @@ sendfile_adapter (struct MHD_Connection *connection)
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;
@@ -407,10 +410,47 @@ sendfile_adapter (struct MHD_Connection *connection)
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 */
return ret;
}
-#endif /* MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE */
+#endif /* _MHD_HAVE_SENDFILE */
/**
@@ -1042,13 +1082,13 @@ try_ready_normal_body (struct MHD_Connection
*connection)
(response->data_size + response->data_start >
connection->response_write_position) )
return MHD_YES; /* response already ready */
-#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined (HAVE_FREEBSD_SENDFILE)
+#if defined(_MHD_HAVE_SENDFILE)
if (MHD_resp_sender_sendfile == connection->resp_sender)
{
/* will use sendfile, no need to bother response crc */
return MHD_YES;
}
-#endif /* MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE */
+#endif /* _MHD_HAVE_SENDFILE */
ret = response->crc (response->crc_cls,
connection->response_write_position,
@@ -2986,15 +3026,15 @@ MHD_connection_handle_write (struct MHD_Connection
*connection)
/* mutex was already unlocked by try_ready_normal_body */
return;
}
-#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE)
+#if defined(_MHD_HAVE_SENDFILE)
if (MHD_resp_sender_sendfile == connection->resp_sender)
{
ret = sendfile_adapter (connection);
}
else
-#else /* ! (MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE) */
+#else /* ! _MHD_HAVE_SENDFILE */
if (1)
-#endif /* ! (MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE) */
+#endif /* ! _MHD_HAVE_SENDFILE */
{
data_write_offset = connection->response_write_position
- response->data_start;
@@ -3934,13 +3974,13 @@ MHD_queue_response (struct MHD_Connection *connection,
MHD_increment_response_rc (response);
connection->response = response;
connection->responseCode = status_code;
-#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE)
+#if defined(_MHD_HAVE_SENDFILE)
if ( (response->fd == -1) ||
(0 != (connection->daemon->options & MHD_USE_TLS)) )
connection->resp_sender = MHD_resp_sender_std;
else
connection->resp_sender = MHD_resp_sender_sendfile;
-#endif /* MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE */
+#endif /* _MHD_HAVE_SENDFILE */
if ( ( (NULL != connection->method) &&
(MHD_str_equal_caseless_ (connection->method,
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 0c986196..70566ea1 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -806,13 +806,13 @@ struct MHD_Connection
*/
uint64_t response_write_position;
-#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE)
+#if defined(_MHD_HAVE_SENDFILE)
enum MHD_resp_sender_
{
MHD_resp_sender_std = 0,
MHD_resp_sender_sendfile
} resp_sender;
-#endif /* MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE */
+#endif /* _MHD_HAVE_SENDFILE */
/**
* Position in the 100 CONTINUE message that
--
To stop receiving notification emails like this one, please contact
address@hidden
- [GNUnet-SVN] [libmicrohttpd] branch master updated (23324164 -> aca29a77), gnunet, 2017/11/22
- [GNUnet-SVN] [libmicrohttpd] 03/05: mhd_limits: improved detection of OFF_T_MAX, SIZE_MAX, added macros for SSIZE_MAX, INT64_MAX, gnunet, 2017/11/22
- [GNUnet-SVN] [libmicrohttpd] 02/05: configure: fixed additional checks for GnuTLS, gnunet, 2017/11/22
- [GNUnet-SVN] [libmicrohttpd] 01/05: mhd_threads: Fixed thread ID data races on pthreads, gnunet, 2017/11/22
- [GNUnet-SVN] [libmicrohttpd] 05/05: Updated .gitignore files, gnunet, 2017/11/22
- [GNUnet-SVN] [libmicrohttpd] 04/05: Added support for Darwin-style sendfile(),
gnunet <=