apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "David Reid" <dr...@jetnet.co.uk>
Subject [PATCH] track socket options...
Date Mon, 08 Jan 2001 22:30:32 GMT
Folks,

This is a small patch that's very much a starting point.  Basically
following Deans suggestion we should be tracking what options we have set on
a socket and using the cached information to avoid system calls.  I've used
an int and the system defined values as that way we can use the mask for non
APR values, i.e. things like TCP_CORK.  By caching the values we also get a
working apr_getsocketopt which is useful.

This throws up some questions though.  Is this the right way to go?  How do
we store things like blocking/non blocking?  Oh well, comments?  Jeff? dean?

I've got a start of a test program but I won't clutter the bandwidth with
that just yet :)  Oh and I know this patch isn't yet ready to commit as it's
not yet complete :)

david

Index: include/arch/unix/networkio.h
===================================================================
RCS file: /home/cvs/apr/include/arch/unix/networkio.h,v
retrieving revision 1.35
diff -u -r1.35 networkio.h
--- include/arch/unix/networkio.h 2000/11/16 14:48:50 1.35
+++ include/arch/unix/networkio.h 2001/01/08 22:09:53
@@ -130,6 +130,7 @@
 #endif
     int local_port_unknown;
     int local_interface_unknown;
+    int netmask;
 };

 struct apr_pollfd_t {
Index: network_io/unix/sockopt.c
===================================================================
RCS file: /home/cvs/apr/network_io/unix/sockopt.c,v
retrieving revision 1.40
diff -u -r1.40 sockopt.c
--- network_io/unix/sockopt.c 2000/12/18 17:00:42 1.40
+++ network_io/unix/sockopt.c 2001/01/08 22:31:08
@@ -55,6 +55,19 @@
 #include "networkio.h"
 #include "apr_strings.h"

+static int is_option_set(int mask, int option)
+{
+    return (mask & option) == option;
+}
+
+static void set_option(int *mask, int option, int on)
+{
+    if (on)
+        *mask |= option;
+    else
+        *mask &= ~option;
+}
+
 static apr_status_t soblock(int sd)
 {
 /* BeOS uses setsockopt at present for non blocking... */
@@ -121,27 +134,39 @@
         one = 0;
     if (opt & APR_SO_KEEPALIVE) {
 #ifdef SO_KEEPALIVE
-        if (setsockopt(sock->socketdes, SOL_SOCKET, SO_KEEPALIVE, (void
*)&one, sizeof(int)) == -1) {
-            return errno;
+        if (on != is_option_set(sock->netmask, SO_KEEPALIVE)){
+            if (setsockopt(sock->socketdes, SOL_SOCKET, SO_KEEPALIVE, (void
*)&one, sizeof(int)) == -1) {
+                return errno;
+            }
+            set_option(&sock->netmask,SO_KEEPALIVE, on);
         }
 #else
         return APR_ENOTIMPL;
 #endif
     }
     if (opt & APR_SO_DEBUG) {
-        if (setsockopt(sock->socketdes, SOL_SOCKET, SO_DEBUG, (void *)&one,
sizeof(int)) == -1) {
-            return errno;
+        if (on != is_option_set(sock->netmask, SO_DEBUG)){
+            if (setsockopt(sock->socketdes, SOL_SOCKET, SO_DEBUG, (void
*)&one, sizeof(int)) == -1) {
+                return errno;
+            }
+            set_option(&sock->netmask, SO_DEBUG, on);
         }
     }
     if (opt & APR_SO_REUSEADDR) {
-        if (setsockopt(sock->socketdes, SOL_SOCKET, SO_REUSEADDR, (void
*)&one, sizeof(int)) == -1) {
-            return errno;
+        if (on != is_option_set(sock->netmask, SO_REUSEADDR)){
+            if (setsockopt(sock->socketdes, SOL_SOCKET, SO_REUSEADDR, (void
*)&one, sizeof(int)) == -1) {
+                return errno;
+            }
+            set_option(&sock->netmask, SO_REUSEADDR, on);
         }
     }
     if (opt & APR_SO_SNDBUF) {
 #ifdef SO_SNDBUF
-        if (setsockopt(sock->socketdes, SOL_SOCKET, SO_SNDBUF, (void *)&on,
sizeof(int)) == -1) {
-            return errno;
+        if (is_option_set(sock->netmask, SO_SNDBUF) != on){
+            if (setsockopt(sock->socketdes, SOL_SOCKET, SO_SNDBUF, (void
*)&on, sizeof(int)) == -1) {
+                return errno;
+            }
+            set_option(&sock->netmask, SO_SNDBUF, on);
         }
 #else
         return APR_ENOTIMPL;
@@ -159,11 +184,14 @@
     }
     if (opt & APR_SO_LINGER) {
 #ifdef SO_LINGER
-        struct linger li;
-        li.l_onoff = on;
-        li.l_linger = MAX_SECS_TO_LINGER;
-        if (setsockopt(sock->socketdes, SOL_SOCKET, SO_LINGER, (char *)
&li, sizeof(struct linger)) == -1) {
-            return errno;
+        if (is_option_set(sock->netmask, SO_LINGER) != on){
+            struct linger li;
+            li.l_onoff = on;
+            li.l_linger = MAX_SECS_TO_LINGER;
+            if (setsockopt(sock->socketdes, SOL_SOCKET, SO_LINGER, (char *)
&li, sizeof(struct linger)) == -1) {
+                return errno;
+            }
+            set_option(&sock->netmask, SO_LINGER, on);
         }
 #else
         return APR_ENOTIMPL;
@@ -183,8 +211,11 @@
     }
     if (opt & APR_TCP_NODELAY) {
 #if defined(TCP_NODELAY)
-        if (setsockopt(sock->socketdes, IPPROTO_TCP, TCP_NODELAY, (void
*)&on, sizeof(int)) == -1) {
-            return errno;
+        if (is_option_set(sock->netmask, TCP_NODELAY) != on){
+            if (setsockopt(sock->socketdes, IPPROTO_TCP, TCP_NODELAY, (void
*)&on, sizeof(int)) == -1) {
+                return errno;
+            }
+            set_option(sock->netmask, TCP_NODELAY, on);
         }
 #else
         /* BeOS pre-BONE has TCP_NODELAY set by default.
@@ -205,11 +236,38 @@
 apr_status_t apr_getsocketopt(apr_socket_t *sock, apr_int32_t opt,
apr_int32_t *on)
 {
     switch(opt) {
-    case APR_SO_TIMEOUT:
-        *on = sock->timeout;
-        break;
-    default:
-        return APR_EINVAL;
+        case APR_SO_KEEPALIVE:
+            *on = is_option_set(sock->netmask, SO_KEEPALIVE);
+            break;
+        case APR_SO_DEBUG:
+            *on = is_option_set(sock->netmask, SO_DEBUG);
+            break;
+        case APR_TCP_NODELAY:
+#ifdef TCP_NODELAY
+            *on = is_option_set(sock->netmask, TCP_NODELAY);
+            break;
+#else
+#if BEOS
+            *on = 1;
+            break;
+#endif
+            return APR_ENOTIMPL;
+#endif
+        case APR_SO_REUSEADDR:
+            *on = is_option_set(sock->netmask, SO_REUSEADDR);
+            break;
+        case APR_SO_SNDBUF:
+#ifdef SO_SNDBUF
+            *on = is_option_set(sock->netmask, SO_SNDBUF);
+            break;
+#else
+            return APR_ENOTIMPL;
+#endif
+        case APR_SO_TIMEOUT:
+            *on = sock->timeout;
+            break;
+        default:
+            return APR_EINVAL;
     }
     return APR_SUCCESS;
 }




Mime
View raw message