OSSP CVS Repository

ossp - Check-in [1137]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 1137
Date: 2001-Oct-09 22:19:58 (local)
2001-Oct-09 20:19:58 (UTC)
User:rse
Branch:
Comment: [still untested stuff]

- Remove SA_TIMEOUT_RECV and SA_TIMEOUT_SEND, because SA_TIMEOUT_READ and SA_TIMEOUT_WRITE are sufficient because you cannot use datagram and stream communication at the same time anyway. So there is no need to distinguish between the two communications in timeouts. Additionally this enables the next point from being able to be implemented at all.

- Implement the read/write timeouts alternatively in kernel-space through the newer SO_RCVTIMEO and SO_SNDTIMEO socket options. This means a select(2) system call less for each read/write operation.

Tickets:
Inspections:
Files:
ossp-pkg/sa/sa.c      1.24 -> 1.25     51 inserted, 5 deleted
ossp-pkg/sa/sa.h      1.19 -> 1.20     1 inserted, 3 deleted

ossp-pkg/sa/sa.c 1.24 -> 1.25

--- sa.c 2001/10/09 19:58:46     1.24
+++ sa.c 2001/10/09 20:19:58     1.25
@@ -163,7 +163,7 @@
 struct sa_st {
     sa_type_t        eType;            /* socket type (stream or datagram) */
     int              fdSocket;         /* socket file descriptor */
-    struct timeval   tvTimeout[6];     /* timeout values (sec, usec) */
+    struct timeval   tvTimeout[4];     /* timeout values (sec, usec) */
     int              nReadLen;         /* read  buffer current length */
     int              nReadSize;        /* read  buffer current size */
     char            *cpReadBuf;        /* read  buffer memory chunk */
@@ -796,6 +796,28 @@
     return SA_OK;
 }
 
+/* set timeouts if timeouts or done in kernel */
+static sa_rc_t sa_socket_settimeouts(sa_t *sa)
+{
+#if defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO)
+    if (sa->fdSocket != -1) {
+        if (SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_READ])) {
+            if (setsockopt(sa->fdSocket, SOL_SOCKET, SO_RCVTIMEO,
+                           &sa->tvTimeout[SA_TIMEOUT_READ],
+                           sizeof(sa->tvTimeout[SA_TIMEOUT_READ])) < 0)
+                return SA_ERR_SYS;
+        }
+        if (SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_WRITE])) {
+            if (setsockopt(sa->fdSocket, SOL_SOCKET, SO_SNDTIMEO,
+                           &sa->tvTimeout[SA_TIMEOUT_WRITE],
+                           sizeof(sa->tvTimeout[SA_TIMEOUT_WRITE])) < 0)
+                return SA_ERR_SYS;
+        }
+    }
+#endif
+    return SA_OK;
+}
+
 /* internal lazy/delayed initialization of underlying socket */
 static sa_rc_t sa_socket_init(sa_t *sa, int nFamily)
 {
@@ -845,6 +867,9 @@
     if ((sa->fdSocket = socket(nFamily, nType, nProto)) == -1)
         return SA_ERR_SYS;
 
+    /* optionally set kernel timeouts */
+    sa_socket_settimeouts(sa);
+
     return SA_OK;
 }
 
@@ -973,6 +998,9 @@
         sa->tvTimeout[id].tv_usec = usec;
     }
 
+    /* optionally set kernel timeouts */
+    sa_socket_settimeouts(sa);
+
     return SA_OK;
 }
 
@@ -1369,10 +1397,13 @@
 static int sa_read_raw(sa_t *sa, char *cpBuf, int nBufLen)
 {
     int rv;
+#if !(defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO))
     fd_set fds;
+#endif
 
     /* if timeout is enabled, perform explicit/smart blocking instead 
        of implicitly/hard blocking in the read(2) system call */
+#if !(defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO))
     if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_READ])) {
         FD_ZERO(&fds);
         FD_SET(sa->fdSocket, &fds);
@@ -1385,12 +1416,18 @@
             return -1;
         }
     }
+#endif
 
     /* perform read operation on underlying socket */
     do {
         rv = SA_SC_CALL_3(sa, read, sa->fdSocket, cpBuf, nBufLen);
     } while (rv == -1 && errno == EINTR);
 
+#if defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO)
+    if (rv == -1 && errno == EWOULDBLOCK)
+        errno = ETIMEDOUT;
+#endif
+
     return rv;
 }
 
@@ -1535,10 +1572,13 @@
 static int sa_write_raw(sa_t *sa, const char *cpBuf, int nBufLen)
 {
     int rv;
+#if !(defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO))
     fd_set fds;
+#endif
 
     /* if timeout is enabled, perform explicit/smart blocking instead 
        of implicitly/hard blocking in the write(2) system call */
+#if !(defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO))
     if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_WRITE])) {
         FD_ZERO(&fds);
         FD_SET(sa->fdSocket, &fds);
@@ -1551,12 +1591,18 @@
             return -1;
         }
     }
+#endif
 
     /* perform write operation on underlying socket */
     do {
         rv = SA_SC_CALL_3(sa, write, sa->fdSocket, cpBuf, nBufLen);
     } while (rv == -1 && errno == EINTR);
 
+#if defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO)
+    if (rv == -1 && errno == EWOULDBLOCK)
+        errno = ETIMEDOUT;
+#endif
+
     return rv;
 }
 
@@ -1756,12 +1802,12 @@
 
     /* if timeout is enabled, perform explicit/smart blocking instead 
        of implicitly/hard blocking in the recvfrom(2) system call */
-    if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_RECV])) {
+    if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_READ])) {
         FD_ZERO(&fds);
         FD_SET(sa->fdSocket, &fds);
         do {
             n = SA_SC_CALL_5(sa, select, sa->fdSocket+1, &fds, NULL, NULL, 
-                             &sa->tvTimeout[SA_TIMEOUT_RECV]);
+                             &sa->tvTimeout[SA_TIMEOUT_READ]);
         } while (n == -1 && errno == EINTR);
         if (n == 0) 
             errno = ETIMEDOUT;
@@ -1812,12 +1858,12 @@
 
     /* if timeout is enabled, perform explicit/smart blocking instead 
        of implicitly/hard blocking in the sendto(2) system call */
-    if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_SEND])) {
+    if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_WRITE])) {
         FD_ZERO(&fds);
         FD_SET(sa->fdSocket, &fds);
         do {
             n = SA_SC_CALL_5(sa, select, sa->fdSocket+1, NULL, &fds, NULL, 
-                             &sa->tvTimeout[SA_TIMEOUT_SEND]);
+                             &sa->tvTimeout[SA_TIMEOUT_WRITE]);
         } while (n == -1 && errno == EINTR);
         if (n == 0) 
             errno = ETIMEDOUT;


ossp-pkg/sa/sa.h 1.19 -> 1.20

--- sa.h 2001/10/09 18:55:22     1.19
+++ sa.h 2001/10/09 20:19:58     1.20
@@ -121,9 +121,7 @@
     SA_TIMEOUT_ACCEPT   = 0,
     SA_TIMEOUT_CONNECT  = 1,
     SA_TIMEOUT_READ     = 2,
-    SA_TIMEOUT_WRITE    = 3,
-    SA_TIMEOUT_RECV     = 4,
-    SA_TIMEOUT_SEND     = 5
+    SA_TIMEOUT_WRITE    = 3
 } sa_timeout_t;
 
 /* list of system calls */

CVSTrac 2.0.1