diff options
author | Junio C Hamano <gitster@pobox.com> | 2016-07-28 11:26:02 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-07-28 11:26:02 -0700 |
commit | 8e4571e57a1a3cc6f1318b3da8612b2e3c8e1252 (patch) | |
tree | 62c096209932596087c620dc7057378534895e27 | |
parent | c81d2836753a268be07346d362ffab3c6a5e14a9 (diff) | |
parent | d751dd11ae16fd4e2410d3a32c8e2d951fafc923 (diff) | |
download | git-8e4571e57a1a3cc6f1318b3da8612b2e3c8e1252.tar.gz |
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
-rw-r--r-- | wrapper.c | 43 |
1 files changed, 27 insertions, 16 deletions
@@ -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; } } |