Deleted Added
full compact
37c37
< __FBSDID("$FreeBSD: head/lib/libc/rpc/svc_vc.c 95658 2002-04-28 15:18:50Z des $");
---
> __FBSDID("$FreeBSD: head/lib/libc/rpc/svc_vc.c 109359 2003-01-16 07:13:51Z mbr $");
53a54
> #include <sys/time.h>
60a62
> #include <fcntl.h>
75a78,79
> extern rwlock_t svc_fd_lock;
>
79a84
> static void __svc_vc_dodestroy (SVCXPRT *);
89a95,96
> static bool_t svc_vc_rendezvous_control (SVCXPRT *xprt, const u_int rq,
> void *in);
95a103
> int maxrec;
102a111,115
> u_int sendsize;
> u_int recvsize;
> int maxrec;
> bool_t nonblock;
> struct timeval last_recv_time;
141a155
> r->maxrec = __svc_maxrec;
288c302
< int sock;
---
> int sock, flags;
289a304
> struct cf_conn *cd;
292a308,309
> SVCXPRT *newxprt;
> fd_set cleanfds;
304c321,330
< return (FALSE);
---
> /*
> * Clean out the most idle file descriptor when we're
> * running out.
> */
> if (errno == EMFILE || errno == ENFILE) {
> cleanfds = svc_fdset;
> __svc_clean_idle(&cleanfds, 0, FALSE);
> goto again;
> }
> return (FALSE);
309,311c335,337
< xprt = makefd_xprt(sock, r->sendsize, r->recvsize);
< xprt->xp_rtaddr.buf = mem_alloc(len);
< if (xprt->xp_rtaddr.buf == NULL)
---
> newxprt = makefd_xprt(sock, r->sendsize, r->recvsize);
> newxprt->xp_rtaddr.buf = mem_alloc(len);
> if (newxprt->xp_rtaddr.buf == NULL)
313,314c339,340
< memcpy(xprt->xp_rtaddr.buf, &addr, len);
< xprt->xp_rtaddr.len = len;
---
> memcpy(newxprt->xp_rtaddr.buf, &addr, len);
> newxprt->xp_rtaddr.len = len;
317,318c343,344
< xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf;
< xprt->xp_addrlen = sizeof (struct sockaddr_in);
---
> newxprt->xp_raddr = *(struct sockaddr_in *)newxprt->xp_rtaddr.buf;
> newxprt->xp_addrlen = sizeof (struct sockaddr_in);
325a352,373
>
> cd = (struct cf_conn *)newxprt->xp_p1;
>
> cd->recvsize = r->recvsize;
> cd->sendsize = r->sendsize;
> cd->maxrec = r->maxrec;
>
> if (cd->maxrec != 0) {
> flags = fcntl(sock, F_GETFL, 0);
> if (flags == -1)
> return (FALSE);
> if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1)
> return (FALSE);
> if (cd->recvsize > cd->maxrec)
> cd->recvsize = cd->maxrec;
> cd->nonblock = TRUE;
> __xdrrec_setnonblock(&cd->xdrs, cd->maxrec);
> } else
> cd->nonblock = FALSE;
>
> gettimeofday(&cd->last_recv_time, NULL);
>
341a390,399
> assert(xprt != NULL);
>
> xprt_unregister(xprt);
> __svc_vc_dodestroy(xprt);
> }
>
> static void
> __svc_vc_dodestroy(xprt)
> SVCXPRT *xprt;
> {
345,346d402
< assert(xprt != NULL);
<
349d404
< xprt_unregister(xprt);
382a438,461
> static bool_t
> svc_vc_rendezvous_control(xprt, rq, in)
> SVCXPRT *xprt;
> const u_int rq;
> void *in;
> {
> struct cf_rendezvous *cfp;
>
> cfp = (struct cf_rendezvous *)xprt->xp_p1;
> if (cfp == NULL)
> return (FALSE);
> switch (rq) {
> case SVCGET_CONNMAXREC:
> *(int *)in = cfp->maxrec;
> break;
> case SVCSET_CONNMAXREC:
> cfp->maxrec = *(int *)in;
> break;
> default:
> return (FALSE);
> }
> return (TRUE);
> }
>
401a481
> struct cf_conn *cfp;
407a488,502
> cfp = (struct cf_conn *)xprt->xp_p1;
>
> if (cfp->nonblock) {
> len = read(sock, buf, (size_t)len);
> if (len < 0) {
> if (errno == EAGAIN)
> len = 0;
> else
> goto fatal_err;
> }
> if (len != 0)
> gettimeofday(&cfp->last_recv_time, NULL);
> return len;
> }
>
435c530,531
< if ((len = _read(sock, buf, (size_t)len)) > 0)
---
> if ((len = read(sock, buf, (size_t)len)) > 0) {
> gettimeofday(&cfp->last_recv_time, NULL);
436a533
> }
456a554,555
> struct cf_conn *cd;
> struct timeval tv0, tv1;
459a559,563
>
> cd = (struct cf_conn *)xprt->xp_p1;
>
> if (cd->nonblock)
> gettimeofday(&tv0, NULL);
462,467c566,573
< if (sa->sa_family == AF_LOCAL) {
< for (cnt = len; cnt > 0; cnt -= i, buf += i) {
< if ((i = __msgwrite(xprt->xp_fd, buf,
< (size_t)cnt)) < 0) {
< ((struct cf_conn *)(xprt->xp_p1))->strm_stat =
< XPRT_DIED;
---
> for (cnt = len; cnt > 0; cnt -= i, buf += i) {
> if (sa->sa_family == AF_LOCAL)
> i = __msgwrite(xprt->xp_fd, buf, (size_t)cnt);
> else
> i = _write(xprt->xp_fd, buf, (size_t)cnt);
> if (i < 0) {
> if (errno != EAGAIN || !cd->nonblock) {
> cd->strm_stat = XPRT_DIED;
470,477c576,588
< }
< } else {
< for (cnt = len; cnt > 0; cnt -= i, buf += i) {
< if ((i = _write(xprt->xp_fd, buf,
< (size_t)cnt)) < 0) {
< ((struct cf_conn *)(xprt->xp_p1))->strm_stat =
< XPRT_DIED;
< return (-1);
---
> if (cd->nonblock && i != cnt) {
> /*
> * For non-blocking connections, do not
> * take more than 2 seconds writing the
> * data out.
> *
> * XXX 2 is an arbitrary amount.
> */
> gettimeofday(&tv1, NULL);
> if (tv1.tv_sec - tv0.tv_sec >= 2) {
> cd->strm_stat = XPRT_DIED;
> return (-1);
> }
515a627,631
> if (cd->nonblock) {
> if (!__xdrrec_getrec(xdrs, &cd->strm_stat, TRUE))
> return FALSE;
> }
>
563c679
< bool_t stat;
---
> bool_t rstat;
573c689
< stat = xdr_replymsg(xdrs, msg);
---
> rstat = xdr_replymsg(xdrs, msg);
575c691
< return (stat);
---
> return (rstat);
622c738
< ops2.xp_control = svc_vc_control;
---
> ops2.xp_control = svc_vc_rendezvous_control;
722a839,888
>
> /*
> * Destroy xprts that have not have had any activity in 'timeout' seconds.
> * If 'cleanblock' is true, blocking connections (the default) are also
> * cleaned. If timeout is 0, the least active connection is picked.
> */
> bool_t
> __svc_clean_idle(fd_set *fds, int timeout, bool_t cleanblock)
> {
> int i, ncleaned;
> SVCXPRT *xprt, *least_active;
> struct timeval tv, tdiff, tmax;
> struct cf_conn *cd;
>
> gettimeofday(&tv, NULL);
> tmax.tv_sec = tmax.tv_usec = 0;
> least_active = NULL;
> rwlock_wrlock(&svc_fd_lock);
> for (i = ncleaned = 0; i <= svc_maxfd; i++) {
> if (FD_ISSET(i, fds)) {
> xprt = __svc_xports[i];
> if (xprt == NULL || xprt->xp_ops == NULL ||
> xprt->xp_ops->xp_recv != svc_vc_recv)
> continue;
> cd = (struct cf_conn *)xprt->xp_p1;
> if (!cleanblock && !cd->nonblock)
> continue;
> if (timeout == 0) {
> timersub(&tv, &cd->last_recv_time, &tdiff);
> if (timercmp(&tdiff, &tmax, >)) {
> tmax = tdiff;
> least_active = xprt;
> }
> continue;
> }
> if (tv.tv_sec - cd->last_recv_time.tv_sec > timeout) {
> __xprt_unregister_unlocked(xprt);
> __svc_vc_dodestroy(xprt);
> ncleaned++;
> }
> }
> }
> if (timeout == 0 && least_active != NULL) {
> __xprt_unregister_unlocked(least_active);
> __svc_vc_dodestroy(least_active);
> ncleaned++;
> }
> rwlock_unlock(&svc_fd_lock);
> return ncleaned > 0 ? TRUE : FALSE;
> }