]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
(readtcp): Also listen to all the other connections and process
authorUlrich Drepper <drepper@redhat.com>
Tue, 7 Jul 1998 12:01:38 +0000 (12:01 +0000)
committerUlrich Drepper <drepper@redhat.com>
Tue, 7 Jul 1998 12:01:38 +0000 (12:01 +0000)
incoming data.

sunrpc/svc_tcp.c

index 627841fff8a337fbd12b24892c7e1107855b3741..50470eede9db4ec2db440447db41aa6f01525690 100644 (file)
@@ -286,45 +286,57 @@ static struct timeval wait_per_try = { 35, 0 };
  * reads data from the tcp connection.
  * any error is fatal and the connection is closed.
  * (And a read of zero bytes is a half closed stream => error.)
+ *
+ * Note: we have to be careful here not to allow ourselves to become
+ * blocked too long in this routine.  While we're waiting for data from one
+ * client, another client may be trying to connect.  To avoid this situation,
+ * some code from svc_run() is transplanted here: the select() loop checks
+ * all RPC descriptors including the one we want and calls svc_getreqset2()
+ * to handle new requests if any are detected.
  */
 static int
-readtcp(xprt, buf, len)
-       register SVCXPRT *xprt;
-       caddr_t buf;
-       register int len;
+readtcp (register SVCXPRT *xprt, caddr_t buf, register int len)
 {
-       register int sock = xprt->xp_sock;
+  int sock = xprt->xp_sock;
 #ifdef FD_SETSIZE
-       fd_set mask;
-       fd_set readfds;
-
-       FD_ZERO(&mask);
-       FD_SET(sock, &mask);
+  fd_set readfds;
 #else
-       register int mask = 1 << sock;
-       int readfds;
+  int mask = 1 << sock;
+  int readfds;
 #endif /* def FD_SETSIZE */
-       do {
-               struct timeval timeout = wait_per_try;
-               readfds = mask;
-               if (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL,
-                          &timeout) <= 0) {
-                       if (errno == EINTR) {
-                               continue;
-                       }
-                       goto fatal_err;
-               }
+  while (1)
+    {
+      struct timeval timeout = wait_per_try;
+      readfds = svc_fdset;
 #ifdef FD_SETSIZE
-       } while (!FD_ISSET(sock, &readfds));
+      FD_SET (sock, &readfds);
 #else
-       } while (readfds != mask);
+      readfds = svc_fds;
+      readfds |= (1 << sock);
 #endif /* def FD_SETSIZE */
-       if ((len = read(sock, buf, len)) > 0) {
-               return (len);
+      if (select (_rpc_dtablesize (), &readfds, (fd_set *) NULL,
+                 (fd_set *) NULL, &timeout) <= 0)
+       {
+         if (errno == EINTR)
+           continue;
+         goto fatal_err;
        }
+#ifdef FD_SETSIZE
+      if (FD_ISSET (sock, &readfds))
+#else
+      if (readfds != mask)
+#endif /* def FD_SETSIZE */
+       break;
+
+      svc_getreqset (&readfds);
+    }
+
+  if ((len = read(sock, buf, len)) > 0)
+    return len;
+
 fatal_err:
-       ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
-       return (-1);
+  ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
+  return -1;
 }
 
 /*