You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by jo...@apache.org on 2005/09/09 10:37:04 UTC
svn commit: r279730 - in /apr/apr/branches/1.2.x: CHANGES
build/apr_network.m4 configure.in network_io/unix/sockopt.c
test/testsockopt.c
Author: jorton
Date: Fri Sep 9 01:36:58 2005
New Revision: 279730
URL: http://svn.apache.org/viewcvs?rev=279730&view=rev
Log:
Merge r240174, r240047, r240181 from trunk:
* network_io/unix/sockopt.c (apr_socket_opt_set): Added a missing
break statement that was causing TCP_NODELAY to be set whenever
TCP_DEFER_ACCEPT was set.
Allow setting both the TCP_NODELAY and TCP_CORK socket options for
Linux >=2.6:
* build/apr_network.m4 (APR_CHECK_TCP_NODELAY_WITH_CORK): New macro.
* configure.in: Use it.
* network_io/unix/sockopt.c (apr_socket_opt_set): If
HAVE_TCP_NODELAY_WITH_CORK is defined, don't toggle TCP_NODELAY when
setting TCP_CORK.
* test/testsockopt.c (corkable): Don't test that TCP_NODELAY and
TCP_CORK are mutually exclusive; caller shouldn't care.
Submitted by: bpane, jorton
Reviewed by: Justin Erenkrantz
Modified:
apr/apr/branches/1.2.x/CHANGES
apr/apr/branches/1.2.x/build/apr_network.m4
apr/apr/branches/1.2.x/configure.in
apr/apr/branches/1.2.x/network_io/unix/sockopt.c
apr/apr/branches/1.2.x/test/testsockopt.c
Modified: apr/apr/branches/1.2.x/CHANGES
URL: http://svn.apache.org/viewcvs/apr/apr/branches/1.2.x/CHANGES?rev=279730&r1=279729&r2=279730&view=diff
==============================================================================
--- apr/apr/branches/1.2.x/CHANGES (original)
+++ apr/apr/branches/1.2.x/CHANGES Fri Sep 9 01:36:58 2005
@@ -1,5 +1,11 @@
Changes for APR 1.2.2
+ *) Fix apr_socket_opt_set() issue where TCP_NODELAY would be
+ set when TCP_DEFER_ACCEPT was set. [Brian Pane]
+
+ *) Allow TCP_NODELAY and TCP_CORK to be set concurrently on
+ Linux 2.6 and later. [Joe Orton]
+
*) Fix apr_socket_addr_get(,APR_REMOTE,) after a non-blocking
connection is completed. PR 32737. [Joe Orton]
Modified: apr/apr/branches/1.2.x/build/apr_network.m4
URL: http://svn.apache.org/viewcvs/apr/apr/branches/1.2.x/build/apr_network.m4?rev=279730&r1=279729&r2=279730&view=diff
==============================================================================
--- apr/apr/branches/1.2.x/build/apr_network.m4 (original)
+++ apr/apr/branches/1.2.x/build/apr_network.m4 Fri Sep 9 01:36:58 2005
@@ -368,6 +368,60 @@
])
dnl
+dnl Determine whether TCP_NODELAY and TCP_CORK can both be set
+dnl on a TCP socket.
+dnl
+AC_DEFUN([APR_CHECK_TCP_NODELAY_WITH_CORK], [
+AC_CACHE_CHECK([whether TCP_NODELAY and TCP_CORK can both be enabled],
+[apr_cv_tcp_nodelay_with_cork],
+[AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+]], [[
+ int fd, flag, rc;
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd < 0) {
+ exit(1);
+ }
+
+ flag = 1;
+ rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof flag);
+ if (rc < 0) {
+ perror("setsockopt TCP_NODELAY");
+ exit(2);
+ }
+
+ flag = 1;
+ rc = setsockopt(fd, IPPROTO_TCP, TCP_CORK, &flag, sizeof flag);
+ if (rc < 0) {
+ perror("setsockopt TCP_CORK");
+ exit(3);
+ }
+
+ exit(0);
+]])], [apr_cv_tcp_nodelay_with_cork=yes], [apr_cv_tcp_nodelay_with_cork=no])])
+
+if test "$apr_cv_tcp_nodelay_with_cork" = "yes"; then
+ AC_DEFINE([HAVE_TCP_NODELAY_WITH_CORK], 1,
+ [Define if TCP_NODELAY and TCP_CORK can be enabled at the same time])
+fi
+])
+
+
+dnl
dnl see if O_NONBLOCK setting is inherited from listening sockets
dnl
AC_DEFUN(APR_CHECK_O_NONBLOCK_INHERITED,[
Modified: apr/apr/branches/1.2.x/configure.in
URL: http://svn.apache.org/viewcvs/apr/apr/branches/1.2.x/configure.in?rev=279730&r1=279729&r2=279730&view=diff
==============================================================================
--- apr/apr/branches/1.2.x/configure.in (original)
+++ apr/apr/branches/1.2.x/configure.in Fri Sep 9 01:36:58 2005
@@ -1875,6 +1875,7 @@
APR_CHECK_TCP_NODELAY_INHERITED
APR_CHECK_O_NONBLOCK_INHERITED
+APR_CHECK_TCP_NODELAY_WITH_CORK
# Look for a way of corking TCP...
APR_CHECK_DEFINE(TCP_CORK, netinet/tcp.h)
Modified: apr/apr/branches/1.2.x/network_io/unix/sockopt.c
URL: http://svn.apache.org/viewcvs/apr/apr/branches/1.2.x/network_io/unix/sockopt.c?rev=279730&r1=279729&r2=279730&view=diff
==============================================================================
--- apr/apr/branches/1.2.x/network_io/unix/sockopt.c (original)
+++ apr/apr/branches/1.2.x/network_io/unix/sockopt.c Fri Sep 9 01:36:58 2005
@@ -210,6 +210,7 @@
#else
return APR_ENOTIMPL;
#endif
+ break;
case APR_TCP_NODELAY:
#if defined(TCP_NODELAY)
if (apr_is_option_set(sock, APR_TCP_NODELAY) != on) {
@@ -242,7 +243,13 @@
break;
case APR_TCP_NOPUSH:
#if APR_TCP_NOPUSH_FLAG
+ /* TCP_NODELAY and TCP_CORK are mutually exclusive on Linux
+ * kernels < 2.6; on newer kernels they can be used together
+ * and TCP_CORK takes preference, which is the desired
+ * behaviour. On older kernels, TCP_NODELAY must be toggled
+ * to "off" whilst TCP_CORK is in effect. */
if (apr_is_option_set(sock, APR_TCP_NOPUSH) != on) {
+#ifndef HAVE_TCP_NODELAY_WITH_CORK
int optlevel = IPPROTO_TCP;
int optname = TCP_NODELAY;
@@ -253,11 +260,9 @@
}
#endif
/* OK we're going to change some settings here... */
- /* TCP_NODELAY is mutually exclusive, so do we have it set? */
if (apr_is_option_set(sock, APR_TCP_NODELAY) == 1 && on) {
- /* If we want to set NOPUSH then if we have the TCP_NODELAY
- * flag set we need to switch it off...
- */
+ /* Now toggle TCP_NODELAY to off, if TCP_CORK is being
+ * turned on: */
int tmpflag = 0;
if (setsockopt(sock->socketdes, optlevel, optname,
(void*)&tmpflag, sizeof(int)) == -1) {
@@ -268,13 +273,19 @@
} else if (on) {
apr_set_option(sock, APR_RESET_NODELAY, 0);
}
+#endif /* HAVE_TCP_NODELAY_WITH_CORK */
+
/* OK, now we can just set the TCP_NOPUSH flag accordingly...*/
if (setsockopt(sock->socketdes, IPPROTO_TCP, APR_TCP_NOPUSH_FLAG,
(void*)&on, sizeof(int)) == -1) {
return errno;
}
apr_set_option(sock, APR_TCP_NOPUSH, on);
+#ifndef HAVE_TCP_NODELAY_WITH_CORK
if (!on && apr_is_option_set(sock, APR_RESET_NODELAY)) {
+ /* Now, if TCP_CORK was just turned off, turn
+ * TCP_NODELAY back on again if it was earlier toggled
+ * to off: */
int tmpflag = 1;
if (setsockopt(sock->socketdes, optlevel, optname,
(void*)&tmpflag, sizeof(int)) == -1) {
@@ -283,6 +294,7 @@
apr_set_option(sock, APR_RESET_NODELAY,0);
apr_set_option(sock, APR_TCP_NODELAY, 1);
}
+#endif /* HAVE_TCP_NODELAY_WITH_CORK */
}
#else
return APR_ENOTIMPL;
Modified: apr/apr/branches/1.2.x/test/testsockopt.c
URL: http://svn.apache.org/viewcvs/apr/apr/branches/1.2.x/test/testsockopt.c?rev=279730&r1=279729&r2=279730&view=diff
==============================================================================
--- apr/apr/branches/1.2.x/test/testsockopt.c (original)
+++ apr/apr/branches/1.2.x/test/testsockopt.c Fri Sep 9 01:36:58 2005
@@ -102,7 +102,9 @@
rv = apr_socket_opt_get(sock, APR_TCP_NODELAY, &ck);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
- ABTS_INT_EQUAL(tc, 0, ck);
+ /* TCP_NODELAY is now in an unknown state; it may be zero if
+ * TCP_NOPUSH and TCP_NODELAY are mutually exclusive on this
+ * platform, e.g. Linux < 2.6. */
rv = apr_socket_opt_set(sock, APR_TCP_NOPUSH, 0);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);