mirror of
git://sourceware.org/git/glibc.git
synced 2025-03-07 13:28:05 +08:00
introduce internal function to ease poll retry with timeout
This commit is contained in:
parent
ab97ee8f1b
commit
c83b8a8717
@ -6,6 +6,46 @@ extern int __poll (struct pollfd *__fds, unsigned long int __nfds,
|
|||||||
int __timeout);
|
int __timeout);
|
||||||
libc_hidden_proto (__poll)
|
libc_hidden_proto (__poll)
|
||||||
libc_hidden_proto (ppoll)
|
libc_hidden_proto (ppoll)
|
||||||
#endif
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__poll_noeintr (struct pollfd *__fds, unsigned long int __nfds,
|
||||||
|
int __timeout)
|
||||||
|
{
|
||||||
|
int __ret = __poll (__fds, __nfds, __timeout);
|
||||||
|
|
||||||
|
if (__ret == -1 && __glibc_unlikely (errno == EINTR))
|
||||||
|
{
|
||||||
|
/* Handle the case where the poll() call is interrupted by a
|
||||||
|
signal. We cannot just use TEMP_FAILURE_RETRY since it might
|
||||||
|
lead to infinite loops. We can't tell how long poll has
|
||||||
|
already waited, and we can't assume the existence of a
|
||||||
|
higher-precision clock, but that's ok-ish: the timeout is a
|
||||||
|
lower bound, we just have to make sure we don't wait
|
||||||
|
indefinitely. */
|
||||||
|
struct timeval __now;
|
||||||
|
(void) __gettimeofday (&__now, NULL);
|
||||||
|
|
||||||
|
long int __end = __now.tv_sec * 1000 + __timeout
|
||||||
|
+ (__now.tv_usec + 500) / 1000;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
__ret = __poll (__fds, __nfds, __timeout);
|
||||||
|
if (__ret != -1 || errno != EINTR)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Recompute the timeout time. */
|
||||||
|
(void) __gettimeofday (&__now, NULL);
|
||||||
|
__timeout = __end - __now.tv_sec * 1000
|
||||||
|
- (__now.tv_usec + 500) / 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return __ret;
|
||||||
|
}
|
||||||
|
#endif /* _ISOMAC */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -215,8 +215,7 @@ internal_nis_do_callback (struct dir_binding *bptr, netobj *cookie,
|
|||||||
my_pollfd[i].revents = 0;
|
my_pollfd[i].revents = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (i = TEMP_FAILURE_RETRY (__poll (my_pollfd, svc_max_pollfd,
|
switch (i = __poll_noeintr (my_pollfd, svc_max_pollfd, 25*1000))
|
||||||
25*1000)))
|
|
||||||
{
|
{
|
||||||
case -1:
|
case -1:
|
||||||
return NIS_CBERROR;
|
return NIS_CBERROR;
|
||||||
|
@ -53,29 +53,7 @@ wait_on_socket (int sock, long int usectmo)
|
|||||||
struct pollfd fds[1];
|
struct pollfd fds[1];
|
||||||
fds[0].fd = sock;
|
fds[0].fd = sock;
|
||||||
fds[0].events = POLLIN | POLLERR | POLLHUP;
|
fds[0].events = POLLIN | POLLERR | POLLHUP;
|
||||||
int n = __poll (fds, 1, usectmo);
|
return __poll_noeintr (fds, 1, usectmo);
|
||||||
if (n == -1 && __builtin_expect (errno == EINTR, 0))
|
|
||||||
{
|
|
||||||
/* Handle the case where the poll() call is interrupted by a
|
|
||||||
signal. We cannot just use TEMP_FAILURE_RETRY since it might
|
|
||||||
lead to infinite loops. */
|
|
||||||
struct timeval now;
|
|
||||||
(void) __gettimeofday (&now, NULL);
|
|
||||||
long int end = now.tv_sec * 1000 + usectmo + (now.tv_usec + 500) / 1000;
|
|
||||||
long int timeout = usectmo;
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
n = __poll (fds, 1, timeout);
|
|
||||||
if (n != -1 || errno != EINTR)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Recompute the timeout time. */
|
|
||||||
(void) __gettimeofday (&now, NULL);
|
|
||||||
timeout = end - (now.tv_sec * 1000 + (now.tv_usec + 500) / 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -378,9 +378,8 @@ send_again:
|
|||||||
anyup = 0;
|
anyup = 0;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
switch (__poll (&fd, 1, milliseconds))
|
switch (__poll_noeintr (&fd, 1, milliseconds))
|
||||||
{
|
{
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
if (anyup == 0)
|
if (anyup == 0)
|
||||||
{
|
{
|
||||||
@ -407,8 +406,6 @@ send_again:
|
|||||||
* updated.
|
* updated.
|
||||||
*/
|
*/
|
||||||
case -1:
|
case -1:
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
cu->cu_error.re_errno = errno;
|
cu->cu_error.re_errno = errno;
|
||||||
return (cu->cu_error.re_status = RPC_CANTRECV);
|
return (cu->cu_error.re_status = RPC_CANTRECV);
|
||||||
}
|
}
|
||||||
|
@ -551,22 +551,16 @@ readunix (char *ctptr, char *buf, int len)
|
|||||||
|
|
||||||
fd.fd = ct->ct_sock;
|
fd.fd = ct->ct_sock;
|
||||||
fd.events = POLLIN;
|
fd.events = POLLIN;
|
||||||
while (TRUE)
|
switch (__poll_noeintr (&fd, 1, milliseconds))
|
||||||
{
|
{
|
||||||
switch (__poll (&fd, 1, milliseconds))
|
case 0:
|
||||||
{
|
ct->ct_error.re_status = RPC_TIMEDOUT;
|
||||||
case 0:
|
return -1;
|
||||||
ct->ct_error.re_status = RPC_TIMEDOUT;
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
case -1:
|
case -1:
|
||||||
if (errno == EINTR)
|
ct->ct_error.re_status = RPC_CANTRECV;
|
||||||
continue;
|
ct->ct_error.re_errno = errno;
|
||||||
ct->ct_error.re_status = RPC_CANTRECV;
|
return -1;
|
||||||
ct->ct_error.re_errno = errno;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
switch (len = __msgread (ct->ct_sock, buf, len))
|
switch (len = __msgread (ct->ct_sock, buf, len))
|
||||||
{
|
{
|
||||||
|
@ -102,9 +102,7 @@ rtime (struct sockaddr_in *addrp, struct rpc_timeval *timep,
|
|||||||
milliseconds = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000);
|
milliseconds = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000);
|
||||||
fd.fd = s;
|
fd.fd = s;
|
||||||
fd.events = POLLIN;
|
fd.events = POLLIN;
|
||||||
do
|
res = __poll_noeintr (&fd, 1, milliseconds);
|
||||||
res = __poll (&fd, 1, milliseconds);
|
|
||||||
while (res < 0 && errno == EINTR);
|
|
||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
{
|
{
|
||||||
if (res == 0)
|
if (res == 0)
|
||||||
|
@ -83,11 +83,9 @@ svc_run (void)
|
|||||||
my_pollfd[i].revents = 0;
|
my_pollfd[i].revents = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (i = __poll (my_pollfd, max_pollfd, -1))
|
switch (i = __poll_noeintr (my_pollfd, max_pollfd, -1))
|
||||||
{
|
{
|
||||||
case -1:
|
case -1:
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
perror (_("svc_run: - poll failed"));
|
perror (_("svc_run: - poll failed"));
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -317,26 +317,19 @@ readtcp (char *xprtptr, char *buf, int len)
|
|||||||
int milliseconds = 35 * 1000;
|
int milliseconds = 35 * 1000;
|
||||||
struct pollfd pollfd;
|
struct pollfd pollfd;
|
||||||
|
|
||||||
do
|
pollfd.fd = sock;
|
||||||
|
pollfd.events = POLLIN;
|
||||||
|
switch (__poll_noeintr (&pollfd, 1, milliseconds))
|
||||||
{
|
{
|
||||||
pollfd.fd = sock;
|
case -1:
|
||||||
pollfd.events = POLLIN;
|
case 0:
|
||||||
switch (__poll (&pollfd, 1, milliseconds))
|
goto fatal_err;
|
||||||
{
|
default:
|
||||||
case -1:
|
if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
|
||||||
if (errno == EINTR)
|
|| (pollfd.revents & POLLNVAL))
|
||||||
continue;
|
goto fatal_err;
|
||||||
/*FALLTHROUGH*/
|
break;
|
||||||
case 0:
|
|
||||||
goto fatal_err;
|
|
||||||
default:
|
|
||||||
if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
|
|
||||||
|| (pollfd.revents & POLLNVAL))
|
|
||||||
goto fatal_err;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while ((pollfd.revents & POLLIN) == 0);
|
|
||||||
|
|
||||||
if ((len = __read (sock, buf, len)) > 0)
|
if ((len = __read (sock, buf, len)) > 0)
|
||||||
return len;
|
return len;
|
||||||
|
@ -419,26 +419,19 @@ readunix (char *xprtptr, char *buf, int len)
|
|||||||
int milliseconds = 35 * 1000;
|
int milliseconds = 35 * 1000;
|
||||||
struct pollfd pollfd;
|
struct pollfd pollfd;
|
||||||
|
|
||||||
do
|
pollfd.fd = sock;
|
||||||
|
pollfd.events = POLLIN;
|
||||||
|
switch (__poll_noeintr (&pollfd, 1, milliseconds))
|
||||||
{
|
{
|
||||||
pollfd.fd = sock;
|
case -1:
|
||||||
pollfd.events = POLLIN;
|
case 0:
|
||||||
switch (__poll (&pollfd, 1, milliseconds))
|
goto fatal_err;
|
||||||
{
|
default:
|
||||||
case -1:
|
if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
|
||||||
if (errno == EINTR)
|
|| (pollfd.revents & POLLNVAL))
|
||||||
continue;
|
goto fatal_err;
|
||||||
/*FALLTHROUGH*/
|
break;
|
||||||
case 0:
|
|
||||||
goto fatal_err;
|
|
||||||
default:
|
|
||||||
if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
|
|
||||||
|| (pollfd.revents & POLLNVAL))
|
|
||||||
goto fatal_err;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while ((pollfd.revents & POLLIN) == 0);
|
|
||||||
|
|
||||||
if ((len = __msgread (sock, buf, len)) > 0)
|
if ((len = __msgread (sock, buf, len)) > 0)
|
||||||
return len;
|
return len;
|
||||||
|
Loading…
Reference in New Issue
Block a user