Deleted Added
full compact
41c41
< __FBSDID("$FreeBSD: head/lib/libc/rpc/clnt_dg.c 99996 2002-07-14 23:14:02Z alfred $");
---
> __FBSDID("$FreeBSD: head/lib/libc/rpc/clnt_dg.c 105189 2002-10-15 22:28:59Z iedowse $");
49d48
< #include <sys/poll.h>
50a50
> #include <sys/event.h>
78d77
< static int __rpc_timeval_to_msec(struct timeval *);
103c102
< thr_sigsetmask(SIG_SETMASK, &(mask), (sigset_t *) NULL); \
---
> thr_sigsetmask(SIG_SETMASK, &(mask), NULL); \
127d125
< struct pollfd pfdp;
130a129,130
> struct kevent cu_kin;
> int cu_kq;
276,277c276,277
< cu->pfdp.fd = cu->cu_fd;
< cu->pfdp.events = POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND;
---
> cu->cu_kq = -1;
> EV_SET(&cu->cu_kin, cu->cu_fd, EVFILT_READ, EV_ADD, 0, 0, 0);
304c304
< size_t outlen;
---
> size_t outlen = 0;
307d306
< struct timeval time_waited;
312,313c311,313
< struct timeval startime, curtime;
< int firsttimeout = 1;
---
> struct timeval next_sendtime, starttime, time_waited, tv;
> struct timespec ts;
> struct kevent kv;
319c319
< int rpc_lock_value;
---
> int kin_len, n, rpc_lock_value;
343d342
< release_fd_lock(cu->cu_fd, mask);
345c344,345
< return (cu->cu_error.re_status = RPC_CANTSEND);
---
> cu->cu_error.re_status = RPC_CANTSEND;
> goto out;
358c358,359
< retransmit_time = cu->cu_wait;
---
> retransmit_time = next_sendtime = cu->cu_wait;
> gettimeofday(&starttime, NULL);
359a361,370
> /* Clean up in case the last call ended in a longjmp(3) call. */
> if (cu->cu_kq >= 0)
> _close(cu->cu_kq);
> if ((cu->cu_kq = kqueue()) < 0) {
> cu->cu_error.re_errno = errno;
> cu->cu_error.re_status = RPC_CANTSEND;
> goto out;
> }
> kin_len = 1;
>
378,379c389,390
< release_fd_lock(cu->cu_fd, mask);
< return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
---
> cu->cu_error.re_status = RPC_CANTENCODEARGS;
> goto out;
386,387c397,398
< release_fd_lock(cu->cu_fd, mask);
< return (cu->cu_error.re_status = RPC_CANTSEND);
---
> cu->cu_error.re_status = RPC_CANTSEND;
> goto out;
394,395c405,406
< release_fd_lock(cu->cu_fd, mask);
< return (cu->cu_error.re_status = RPC_TIMEDOUT);
---
> cu->cu_error.re_status = RPC_TIMEDOUT;
> goto out;
409d419
<
411,428c421,428
< switch (_poll(&cu->pfdp, 1,
< __rpc_timeval_to_msec(&retransmit_time))) {
< case 0:
< time_waited.tv_sec += retransmit_time.tv_sec;
< time_waited.tv_usec += retransmit_time.tv_usec;
< while (time_waited.tv_usec >= 1000000) {
< time_waited.tv_sec++;
< time_waited.tv_usec -= 1000000;
< }
< /* update retransmit_time */
< if (retransmit_time.tv_sec < RPC_MAX_BACKOFF) {
< retransmit_time.tv_usec *= 2;
< retransmit_time.tv_sec *= 2;
< while (retransmit_time.tv_usec >= 1000000) {
< retransmit_time.tv_sec++;
< retransmit_time.tv_usec -= 1000000;
< }
< }
---
> /* Decide how long to wait. */
> if (timercmp(&next_sendtime, &timeout, <))
> timersub(&next_sendtime, &time_waited, &tv);
> else
> timersub(&timeout, &time_waited, &tv);
> if (tv.tv_sec < 0 || tv.tv_usec < 0)
> tv.tv_sec = tv.tv_usec = 0;
> TIMEVAL_TO_TIMESPEC(&tv, &ts);
430,435c430,432
< if ((time_waited.tv_sec < timeout.tv_sec) ||
< ((time_waited.tv_sec == timeout.tv_sec) &&
< (time_waited.tv_usec < timeout.tv_usec)))
< goto send_again;
< release_fd_lock(cu->cu_fd, mask);
< return (cu->cu_error.re_status = RPC_TIMEDOUT);
---
> n = _kevent(cu->cu_kq, &cu->cu_kin, kin_len, &kv, 1, &ts);
> /* We don't need to register the event again. */
> kin_len = 0;
437,438c434,445
< case -1:
< if (errno == EBADF) {
---
> if (n == 1) {
> if (kv.flags & EV_ERROR) {
> cu->cu_error.re_errno = kv.data;
> cu->cu_error.re_status = RPC_CANTRECV;
> goto out;
> }
> /* We have some data now */
> do {
> recvlen = _recvfrom(cu->cu_fd, cu->cu_inbuf,
> cu->cu_recvsz, 0, NULL, NULL);
> } while (recvlen < 0 && errno == EINTR);
> if (recvlen < 0 && errno != EWOULDBLOCK) {
440,441c447,448
< release_fd_lock(cu->cu_fd, mask);
< return (cu->cu_error.re_status = RPC_CANTRECV);
---
> cu->cu_error.re_status = RPC_CANTRECV;
> goto out;
443,445c450,455
< if (errno != EINTR) {
< errno = 0; /* reset it */
< continue;
---
> if (recvlen >= sizeof(u_int32_t) &&
> (cu->cu_async == TRUE ||
> *((u_int32_t *)(void *)(cu->cu_inbuf)) ==
> *((u_int32_t *)(void *)(cu->cu_outbuf)))) {
> /* We now assume we have the proper reply. */
> break;
447,491c457,459
< /* interrupted by another signal, update time_waited */
< if (firsttimeout) {
< /*
< * Could have done gettimeofday before clnt_call
< * but that means 1 more system call per each
< * clnt_call, so do it after first time out
< */
< if (gettimeofday(&startime,
< (struct timezone *) NULL) == -1) {
< errno = 0;
< continue;
< }
< firsttimeout = 0;
< errno = 0;
< continue;
< };
< if (gettimeofday(&curtime,
< (struct timezone *) NULL) == -1) {
< errno = 0;
< continue;
< };
< time_waited.tv_sec += curtime.tv_sec - startime.tv_sec;
< time_waited.tv_usec += curtime.tv_usec -
< startime.tv_usec;
< while (time_waited.tv_usec < 0) {
< time_waited.tv_sec--;
< time_waited.tv_usec += 1000000;
< };
< while (time_waited.tv_usec >= 1000000) {
< time_waited.tv_sec++;
< time_waited.tv_usec -= 1000000;
< }
< startime.tv_sec = curtime.tv_sec;
< startime.tv_usec = curtime.tv_usec;
< if ((time_waited.tv_sec > timeout.tv_sec) ||
< ((time_waited.tv_sec == timeout.tv_sec) &&
< (time_waited.tv_usec > timeout.tv_usec))) {
< release_fd_lock(cu->cu_fd, mask);
< return (cu->cu_error.re_status = RPC_TIMEDOUT);
< }
< errno = 0; /* reset it */
< continue;
< };
<
< if (cu->pfdp.revents & POLLNVAL || (cu->pfdp.revents == 0)) {
---
> }
> if (n == -1 && errno != EINTR) {
> cu->cu_error.re_errno = errno;
493,502c461
< /*
< * Note: we're faking errno here because we
< * previously would have expected _poll() to
< * return -1 with errno EBADF. Poll(BA_OS)
< * returns 0 and sets the POLLNVAL revents flag
< * instead.
< */
< cu->cu_error.re_errno = errno = EBADF;
< release_fd_lock(cu->cu_fd, mask);
< return (-1);
---
> goto out;
503a463,464
> gettimeofday(&tv, NULL);
> timersub(&tv, &starttime, &time_waited);
505,522c466,469
< /* We have some data now */
< do {
< if (errno == EINTR) {
< /*
< * Must make sure errno was not already
< * EINTR in case _recvfrom() returns -1.
< */
< errno = 0;
< }
< recvlen = _recvfrom(cu->cu_fd, cu->cu_inbuf,
< cu->cu_recvsz, 0, NULL, NULL);
< } while (recvlen < 0 && errno == EINTR);
< if (recvlen < 0) {
< if (errno == EWOULDBLOCK)
< continue;
< cu->cu_error.re_errno = errno;
< release_fd_lock(cu->cu_fd, mask);
< return (cu->cu_error.re_status = RPC_CANTRECV);
---
> /* Check for timeout. */
> if (timercmp(&time_waited, &timeout, >)) {
> cu->cu_error.re_status = RPC_TIMEDOUT;
> goto out;
524,532c471,481
< if (recvlen < sizeof (u_int32_t))
< continue;
< /* see if reply transaction id matches sent id */
< if (cu->cu_async == FALSE &&
< *((u_int32_t *)(void *)(cu->cu_inbuf)) !=
< *((u_int32_t *)(void *)(cu->cu_outbuf)))
< continue;
< /* we now assume we have the proper reply */
< break;
---
>
> /* Retransmit if necessary. */
> if (timercmp(&time_waited, &next_sendtime, >)) {
> /* update retransmit_time */
> if (retransmit_time.tv_sec < RPC_MAX_BACKOFF)
> timeradd(&retransmit_time, &retransmit_time,
> &retransmit_time);
> timeradd(&next_sendtime, &retransmit_time,
> &next_sendtime);
> goto send_again;
> }
578a528,531
> out:
> if (cu->cu_kq >= 0)
> _close(cu->cu_kq);
> cu->cu_kq = -1;
786a740,741
> if (cu->cu_kq >= 0)
> _close(cu->cu_kq);
836,858d790
<
< /*
< * Convert from timevals (used by select) to milliseconds (used by poll).
< */
< static int
< __rpc_timeval_to_msec(t)
< struct timeval *t;
< {
< int t1, tmp;
<
< /*
< * We're really returning t->tv_sec * 1000 + (t->tv_usec / 1000)
< * but try to do so efficiently. Note: 1000 = 1024 - 16 - 8.
< */
< tmp = (int)t->tv_sec << 3;
< t1 = -tmp;
< t1 += t1 << 1;
< t1 += tmp << 7;
< if (t->tv_usec)
< t1 += (int)(t->tv_usec / 1000);
<
< return (t1);
< }