mirror of
git://sourceware.org/git/glibc.git
synced 2024-12-15 04:20:28 +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);
|
||||
libc_hidden_proto (__poll)
|
||||
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
|
||||
|
@ -215,8 +215,7 @@ internal_nis_do_callback (struct dir_binding *bptr, netobj *cookie,
|
||||
my_pollfd[i].revents = 0;
|
||||
}
|
||||
|
||||
switch (i = TEMP_FAILURE_RETRY (__poll (my_pollfd, svc_max_pollfd,
|
||||
25*1000)))
|
||||
switch (i = __poll_noeintr (my_pollfd, svc_max_pollfd, 25*1000))
|
||||
{
|
||||
case -1:
|
||||
return NIS_CBERROR;
|
||||
|
@ -53,29 +53,7 @@ wait_on_socket (int sock, long int usectmo)
|
||||
struct pollfd fds[1];
|
||||
fds[0].fd = sock;
|
||||
fds[0].events = POLLIN | POLLERR | POLLHUP;
|
||||
int n = __poll (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;
|
||||
return __poll_noeintr (fds, 1, usectmo);
|
||||
}
|
||||
|
||||
|
||||
|
@ -378,9 +378,8 @@ send_again:
|
||||
anyup = 0;
|
||||
for (;;)
|
||||
{
|
||||
switch (__poll (&fd, 1, milliseconds))
|
||||
switch (__poll_noeintr (&fd, 1, milliseconds))
|
||||
{
|
||||
|
||||
case 0:
|
||||
if (anyup == 0)
|
||||
{
|
||||
@ -407,8 +406,6 @@ send_again:
|
||||
* updated.
|
||||
*/
|
||||
case -1:
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
cu->cu_error.re_errno = errno;
|
||||
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.events = POLLIN;
|
||||
while (TRUE)
|
||||
switch (__poll_noeintr (&fd, 1, milliseconds))
|
||||
{
|
||||
switch (__poll (&fd, 1, milliseconds))
|
||||
{
|
||||
case 0:
|
||||
ct->ct_error.re_status = RPC_TIMEDOUT;
|
||||
return -1;
|
||||
case 0:
|
||||
ct->ct_error.re_status = RPC_TIMEDOUT;
|
||||
return -1;
|
||||
|
||||
case -1:
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
ct->ct_error.re_status = RPC_CANTRECV;
|
||||
ct->ct_error.re_errno = errno;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case -1:
|
||||
ct->ct_error.re_status = RPC_CANTRECV;
|
||||
ct->ct_error.re_errno = errno;
|
||||
return -1;
|
||||
}
|
||||
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);
|
||||
fd.fd = s;
|
||||
fd.events = POLLIN;
|
||||
do
|
||||
res = __poll (&fd, 1, milliseconds);
|
||||
while (res < 0 && errno == EINTR);
|
||||
res = __poll_noeintr (&fd, 1, milliseconds);
|
||||
if (res <= 0)
|
||||
{
|
||||
if (res == 0)
|
||||
|
@ -83,11 +83,9 @@ svc_run (void)
|
||||
my_pollfd[i].revents = 0;
|
||||
}
|
||||
|
||||
switch (i = __poll (my_pollfd, max_pollfd, -1))
|
||||
switch (i = __poll_noeintr (my_pollfd, max_pollfd, -1))
|
||||
{
|
||||
case -1:
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
perror (_("svc_run: - poll failed"));
|
||||
break;
|
||||
case 0:
|
||||
|
@ -317,26 +317,19 @@ readtcp (char *xprtptr, char *buf, int len)
|
||||
int milliseconds = 35 * 1000;
|
||||
struct pollfd pollfd;
|
||||
|
||||
do
|
||||
pollfd.fd = sock;
|
||||
pollfd.events = POLLIN;
|
||||
switch (__poll_noeintr (&pollfd, 1, milliseconds))
|
||||
{
|
||||
pollfd.fd = sock;
|
||||
pollfd.events = POLLIN;
|
||||
switch (__poll (&pollfd, 1, milliseconds))
|
||||
{
|
||||
case -1:
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
/*FALLTHROUGH*/
|
||||
case 0:
|
||||
goto fatal_err;
|
||||
default:
|
||||
if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
|
||||
|| (pollfd.revents & POLLNVAL))
|
||||
goto fatal_err;
|
||||
break;
|
||||
}
|
||||
case -1:
|
||||
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)
|
||||
return len;
|
||||
|
@ -419,26 +419,19 @@ readunix (char *xprtptr, char *buf, int len)
|
||||
int milliseconds = 35 * 1000;
|
||||
struct pollfd pollfd;
|
||||
|
||||
do
|
||||
pollfd.fd = sock;
|
||||
pollfd.events = POLLIN;
|
||||
switch (__poll_noeintr (&pollfd, 1, milliseconds))
|
||||
{
|
||||
pollfd.fd = sock;
|
||||
pollfd.events = POLLIN;
|
||||
switch (__poll (&pollfd, 1, milliseconds))
|
||||
{
|
||||
case -1:
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
/*FALLTHROUGH*/
|
||||
case 0:
|
||||
goto fatal_err;
|
||||
default:
|
||||
if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
|
||||
|| (pollfd.revents & POLLNVAL))
|
||||
goto fatal_err;
|
||||
break;
|
||||
}
|
||||
case -1:
|
||||
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)
|
||||
return len;
|
||||
|
Loading…
Reference in New Issue
Block a user