1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-10-28 21:07:52 +01:00

Merge branch 'sb/submodule-parallel-fetch'

Fix recently introduced codepaths that are involved in parallel
submodule operations, which gave up on reading too early, and
could have wasted CPU while attempting to write under a corner
case condition.

* sb/submodule-parallel-fetch:
  hoist out handle_nonblock function for xread and xwrite
  xwrite: poll on non-blocking FDs
  xread: retry after poll on EAGAIN/EWOULDBLOCK
This commit is contained in:
Junio C Hamano 2016-07-19 13:22:14 -07:00
commit 7725bebe21

View file

@ -227,6 +227,24 @@ int xopen(const char *path, int oflag, ...)
}
}
static int handle_nonblock(int fd, short poll_events, int err)
{
struct pollfd pfd;
if (err != EAGAIN && err != EWOULDBLOCK)
return 0;
pfd.fd = fd;
pfd.events = poll_events;
/*
* no need to check for errors, here;
* a subsequent read/write will detect unrecoverable errors
*/
poll(&pfd, 1, -1);
return 1;
}
/*
* xread() is the same a read(), but it automatically restarts read()
* operations with a recoverable error (EAGAIN and EINTR). xread()
@ -242,20 +260,8 @@ ssize_t xread(int fd, void *buf, size_t len)
if (nr < 0) {
if (errno == EINTR)
continue;
if (errno == EAGAIN || errno == EWOULDBLOCK) {
struct pollfd pfd;
pfd.events = POLLIN;
pfd.fd = fd;
/*
* it is OK if this poll() failed; we
* want to leave this infinite loop
* only when read() returns with
* success, or an expected failure,
* which would be checked by the next
* call to read(2).
*/
poll(&pfd, 1, -1);
}
if (handle_nonblock(fd, POLLIN, errno))
continue;
}
return nr;
}
@ -273,8 +279,13 @@ ssize_t xwrite(int fd, const void *buf, size_t len)
len = MAX_IO_SIZE;
while (1) {
nr = write(fd, buf, len);
if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
continue;
if (nr < 0) {
if (errno == EINTR)
continue;
if (handle_nonblock(fd, POLLOUT, errno))
continue;
}
return nr;
}
}