fix(ipc): retry nonblocking I/O until deadline
This commit is contained in:
29
ipc.c
29
ipc.c
@@ -33,6 +33,21 @@ deadline(void)
|
||||
return now + Ipcwaitms;
|
||||
}
|
||||
|
||||
static int
|
||||
checkdeadline(int64_t until)
|
||||
{
|
||||
int64_t now;
|
||||
|
||||
now = nowms();
|
||||
if(now < 0)
|
||||
return -1;
|
||||
if(now >= until){
|
||||
errno = ETIMEDOUT;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
waitfd(int fd, short events, int64_t until)
|
||||
{
|
||||
@@ -78,13 +93,16 @@ readwait(int fd, void *buf, size_t n, int64_t until)
|
||||
|
||||
p = buf;
|
||||
while(n > 0){
|
||||
if(waitfd(fd, POLLIN, until) < 0)
|
||||
if(checkdeadline(until) < 0)
|
||||
return -1;
|
||||
r = recv(fd, p, n, MSG_DONTWAIT);
|
||||
if(r < 0 && errno == EINTR)
|
||||
continue;
|
||||
if(r < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
|
||||
if(r < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)){
|
||||
if(waitfd(fd, POLLIN, until) < 0)
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
if(r < 0)
|
||||
return -1;
|
||||
if(r == 0){
|
||||
@@ -380,13 +398,16 @@ ipcsend(int fd, const void *buf, size_t n)
|
||||
if(until < 0)
|
||||
return -1;
|
||||
while(n > 0){
|
||||
if(waitfd(fd, POLLOUT, until) < 0)
|
||||
if(checkdeadline(until) < 0)
|
||||
return -1;
|
||||
r = send(fd, p, n, MSG_NOSIGNAL|MSG_DONTWAIT);
|
||||
if(r < 0 && errno == EINTR)
|
||||
continue;
|
||||
if(r < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
|
||||
if(r < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)){
|
||||
if(waitfd(fd, POLLOUT, until) < 0)
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
if(r < 0)
|
||||
return -1;
|
||||
if(r == 0){
|
||||
|
||||
Reference in New Issue
Block a user