The attached patch delays the setting of TCP_NODELAY on client connections until the first time core_output_filter has to do a writev_it_all() or emulate_sendfile(). My motivation for this is to work around the TCP_NODELAY/TCP_CORK problem in Linux 2.6. However, it also will save a couple of syscalls for any request that
is handled with sendfile(2).

Note that there was an APR bug that caused TCP_NODELAY to be set on the
listener socket at startup as a side-effect of TCP_DEFER_ACCEPT being set. I just committed a fix for this. Without that fix, Linux 2.6 systems using this httpd
patch will still exhibit the corking problem.

Can a couple of volunteers please test and/or review this patch? I'd appreciate a second opinion before I commit, given the subtlety of the NODELAY and CORK
semantics on various platforms.

Thanks,
Brian
Index: server/core.c
===================================================================
--- server/core.c       (revision 240169)
+++ server/core.c       (working copy)
@@ -3827,25 +3827,6 @@
 {
     core_net_rec *net = apr_palloc(c->pool, sizeof(*net));
 
-#ifdef AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK
-    apr_status_t rv;
-
-    /* The Nagle algorithm says that we should delay sending partial
-     * packets in hopes of getting more data.  We don't want to do
-     * this; we are not telnet.  There are bad interactions between
-     * persistent connections and Nagle's algorithm that have very severe
-     * performance penalties.  (Failing to disable Nagle is not much of a
-     * problem with simple HTTP.)
-     */
-    rv = apr_socket_opt_set(csd, APR_TCP_NODELAY, 1);
-    if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) {
-        /* expected cause is that the client disconnected already,
-         * hence the debug level
-         */
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c,
-                      "apr_socket_opt_set(APR_TCP_NODELAY)");
-    }
-#endif
     net->c = c;
     net->in_ctx = NULL;
     net->out_ctx = NULL;
Index: server/listen.c
===================================================================
--- server/listen.c     (revision 240164)
+++ server/listen.c     (working copy)
@@ -126,10 +126,6 @@
         }
     }
 
-#if APR_TCP_NODELAY_INHERITED
-    ap_sock_disable_nagle(s);
-#endif
-
     if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) {
         ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p,
                       "make_sock: could not bind to address %pI",
Index: server/core_filters.c
===================================================================
--- server/core_filters.c       (revision 240164)
+++ server/core_filters.c       (working copy)
@@ -887,6 +887,10 @@
             else
 #endif
             {
+#ifdef AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK
+                (void)apr_socket_opt_set(net->client_socket,
+                                         APR_TCP_NODELAY, 1);
+#endif
                 rv = emulate_sendfile(net, fd, &hdtr, foffset, flen,
                                       &bytes_sent);
             }
@@ -898,7 +902,9 @@
         }
         else {
             apr_size_t bytes_sent;
-
+#ifdef AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK
+            (void)apr_socket_opt_set(net->client_socket, APR_TCP_NODELAY, 1);
+#endif
             rv = writev_it_all(net->client_socket,
                                vec, nvec,
                                nbytes, &bytes_sent);

Reply via email to