From: Ulrich Drepper Date: Tue, 7 Jul 1998 12:01:38 +0000 (+0000) Subject: (readtcp): Also listen to all the other connections and process X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d4c7a69d24c66b159daa9b68479590d64ed2347b;p=thirdparty%2Fglibc.git (readtcp): Also listen to all the other connections and process incoming data. --- diff --git a/sunrpc/svc_tcp.c b/sunrpc/svc_tcp.c index 627841fff8a..50470eede9d 100644 --- a/sunrpc/svc_tcp.c +++ b/sunrpc/svc_tcp.c @@ -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; } /*