fix(ipc): retry nonblocking I/O until deadline

This commit is contained in:
2026-08-15 15:07:07 +09:00
parent d29d43f443
commit f489c56fb1

29
ipc.c
View File

@@ -33,6 +33,21 @@ deadline(void)
return now + Ipcwaitms; 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 static int
waitfd(int fd, short events, int64_t until) 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; p = buf;
while(n > 0){ while(n > 0){
if(waitfd(fd, POLLIN, until) < 0) if(checkdeadline(until) < 0)
return -1; return -1;
r = recv(fd, p, n, MSG_DONTWAIT); r = recv(fd, p, n, MSG_DONTWAIT);
if(r < 0 && errno == EINTR) if(r < 0 && errno == EINTR)
continue; continue;
if(r < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) if(r < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)){
if(waitfd(fd, POLLIN, until) < 0)
return -1;
continue; continue;
}
if(r < 0) if(r < 0)
return -1; return -1;
if(r == 0){ if(r == 0){
@@ -380,13 +398,16 @@ ipcsend(int fd, const void *buf, size_t n)
if(until < 0) if(until < 0)
return -1; return -1;
while(n > 0){ while(n > 0){
if(waitfd(fd, POLLOUT, until) < 0) if(checkdeadline(until) < 0)
return -1; return -1;
r = send(fd, p, n, MSG_NOSIGNAL|MSG_DONTWAIT); r = send(fd, p, n, MSG_NOSIGNAL|MSG_DONTWAIT);
if(r < 0 && errno == EINTR) if(r < 0 && errno == EINTR)
continue; continue;
if(r < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) if(r < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)){
if(waitfd(fd, POLLOUT, until) < 0)
return -1;
continue; continue;
}
if(r < 0) if(r < 0)
return -1; return -1;
if(r == 0){ if(r == 0){