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;
|
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){
|
||||||
|
|||||||
Reference in New Issue
Block a user