зеркало из https://github.com/microsoft/git.git
Merge branch 'sb/submodule-parallel-fetch' into maint
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:
Коммит
8e4571e57a
43
wrapper.c
43
wrapper.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче