Skip to content

Commit 8e4571e

Browse files
committed
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
2 parents c81d283 + d751dd1 commit 8e4571e

File tree

1 file changed

+27
-16
lines changed

1 file changed

+27
-16
lines changed

wrapper.c

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,24 @@ int xopen(const char *path, int oflag, ...)
227227
}
228228
}
229229

230+
static int handle_nonblock(int fd, short poll_events, int err)
231+
{
232+
struct pollfd pfd;
233+
234+
if (err != EAGAIN && err != EWOULDBLOCK)
235+
return 0;
236+
237+
pfd.fd = fd;
238+
pfd.events = poll_events;
239+
240+
/*
241+
* no need to check for errors, here;
242+
* a subsequent read/write will detect unrecoverable errors
243+
*/
244+
poll(&pfd, 1, -1);
245+
return 1;
246+
}
247+
230248
/*
231249
* xread() is the same a read(), but it automatically restarts read()
232250
* operations with a recoverable error (EAGAIN and EINTR). xread()
@@ -242,20 +260,8 @@ ssize_t xread(int fd, void *buf, size_t len)
242260
if (nr < 0) {
243261
if (errno == EINTR)
244262
continue;
245-
if (errno == EAGAIN || errno == EWOULDBLOCK) {
246-
struct pollfd pfd;
247-
pfd.events = POLLIN;
248-
pfd.fd = fd;
249-
/*
250-
* it is OK if this poll() failed; we
251-
* want to leave this infinite loop
252-
* only when read() returns with
253-
* success, or an expected failure,
254-
* which would be checked by the next
255-
* call to read(2).
256-
*/
257-
poll(&pfd, 1, -1);
258-
}
263+
if (handle_nonblock(fd, POLLIN, errno))
264+
continue;
259265
}
260266
return nr;
261267
}
@@ -273,8 +279,13 @@ ssize_t xwrite(int fd, const void *buf, size_t len)
273279
len = MAX_IO_SIZE;
274280
while (1) {
275281
nr = write(fd, buf, len);
276-
if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
277-
continue;
282+
if (nr < 0) {
283+
if (errno == EINTR)
284+
continue;
285+
if (handle_nonblock(fd, POLLOUT, errno))
286+
continue;
287+
}
288+
278289
return nr;
279290
}
280291
}

0 commit comments

Comments
 (0)