commit 602a14fb5d0e81e1f59bf8e1012cbb034d978fe4
parent bd05eb27037144c3058c30dc20640d4b1ffa68a3
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date: Wed, 25 Nov 2015 18:45:22 +0000
Reduce last packet response delay observable with keep-alive on BSD and Darwin platforms
Diffstat:
5 files changed, 55 insertions(+), 20 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,7 @@
+Wed Nov 25 17:02:53 CET 2015
+ Remove 200ms delay observable with keep-alive on Darwin
+ and *BSD platfroms. -EG
+
Tue Nov 10 15:25:48 CET 2015
Fix issue with shutdown if connection was resumed just
before shutdown. -FC
diff --git a/configure.ac b/configure.ac
@@ -544,9 +544,6 @@ have_inet6=no
])
AC_MSG_RESULT($have_inet6)
-# TCP_CORK and TCP_NOPUSH
-AC_CHECK_DECLS([TCP_CORK, TCP_NOPUSH], [], [], [[#include <netinet/tcp.h>]])
-
HIDDEN_VISIBILITY_CFLAGS=""
case "$host" in
*-*-mingw*)
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
@@ -130,7 +130,7 @@ typedef intptr_t ssize_t;
* Current version of the library.
* 0x01093001 = 1.9.30-1.
*/
-#define MHD_VERSION 0x00094602
+#define MHD_VERSION 0x00094603
/**
* MHD-internal return code for "YES".
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
@@ -2422,14 +2422,29 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
}
connection->state = MHD_CONNECTION_HEADERS_SENDING;
-#if HAVE_DECL_TCP_CORK
- /* starting header send, set TCP cork */
- {
+ /* starting send, prefer fill full buffer before sending */
+#if defined(TCP_CORK)
+ { /* Send only full packets */
const _MHD_SOCKOPT_BOOL_TYPE val = 1;
setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &val,
sizeof (val));
}
-#endif
+#elif defined(TCP_NODELAY) || defined(TCP_NOPUSH)
+#if defined(TCP_NOPUSH)
+ { /* Buffer data before sending */
+ const _MHD_SOCKOPT_BOOL_TYPE on_val = 1;
+ setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NOPUSH, (const void*)&on_val,
+ sizeof (on_val));
+ }
+#endif /* TCP_NOPUSH */
+#if defined(TCP_NODELAY)
+ { /* Enable Nagle's algorithm, even if it was disabled somehow */
+ const _MHD_SOCKOPT_BOOL_TYPE off_val = 0;
+ setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NODELAY, (const void*)&off_val,
+ sizeof (off_val));
+ }
+#endif /* TCP_NODELAY */
+#endif /* TCP_NODELAY || TCP_NOPUSH */
break;
case MHD_CONNECTION_HEADERS_SENDING:
/* no default action */
@@ -2506,14 +2521,35 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
/* no default action */
break;
case MHD_CONNECTION_FOOTERS_SENT:
-#if HAVE_DECL_TCP_CORK
- /* done sending, uncork */
- {
+ /* done sending, send last partial packet immediately if possible */
+#if defined(TCP_CORK)
+ { /* Flush buffered data, allow partial packets */
const _MHD_SOCKOPT_BOOL_TYPE val = 0;
setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &val,
sizeof (val));
}
-#endif
+#elif defined(TCP_NODELAY) || defined(TCP_NOPUSH)
+#if defined(TCP_NODELAY)
+ { /* Disable Nagle's algorithm to push partial packet */
+ const _MHD_SOCKOPT_BOOL_TYPE on_val = 1;
+ setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NODELAY, (const void*)&on_val,
+ sizeof (on_val));
+ }
+#endif /* TCP_NODELAY */
+#if defined(TCP_NOPUSH)
+ { /* Send data without extra buffering, may flush pending data on some platforms */
+ const _MHD_SOCKOPT_BOOL_TYPE off_val = 0;
+ setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NOPUSH, (const void*)&off_val,
+ sizeof (off_val));
+ }
+#endif /* TCP_NOPUSH */
+ { /* force flush data with zero send otherwise Darwin and some BSD systems
+ will add 5 seconds delay */
+ const int dummy = 0;
+ (void)send (connection->socket_fd, (const void*)&dummy, 0, 0);
+ }
+#endif /* TCP_NODELAY || TCP_NOPUSH */
+
end =
MHD_get_response_header (connection->response,
MHD_HTTP_HEADER_CONNECTION);
@@ -2557,6 +2593,12 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
else
{
/* can try to keep-alive */
+#if !defined(TCP_CORK) && defined(TCP_NODELAY)
+ /* Enable Nagle's algorithm */
+ const _MHD_SOCKOPT_BOOL_TYPE off_val = 0;
+ setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NODELAY, (const void*)&off_val,
+ sizeof (off_val));
+#endif /* !TCP_CORK && TCP_NODELAY */
connection->version = NULL;
connection->state = MHD_CONNECTION_INIT;
/* Reset the read buffer to the starting size,
diff --git a/w32/VS2013/MHD_config.h b/w32/VS2013/MHD_config.h
@@ -62,14 +62,6 @@
don't. */
#define HAVE_DECL_SOCK_NONBLOCK 0
-/* Define to 1 if you have the declaration of `TCP_CORK', and to 0 if you
- don't. */
-#define HAVE_DECL_TCP_CORK 0
-
-/* Define to 1 if you have the declaration of `TCP_NOPUSH', and to 0 if you
- don't. */
-#define HAVE_DECL_TCP_NOPUSH 0
-
/* Define to 1 if you have the `_lseeki64' function. */
#define HAVE___LSEEKI64 1