From: Junio C Hamano Date: Tue, 12 Jan 2016 23:16:54 +0000 (-0800) Subject: Merge branch 'sb/submodule-parallel-fetch' X-Git-Tag: v2.8.0-rc0~127 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/187c0d3d9e63f7d84d7055372f07bedb52849f06?hp=-c Merge branch 'sb/submodule-parallel-fetch' Add a framework to spawn a group of processes in parallel, and use it to run "git fetch --recurse-submodules" in parallel. Rerolled and this seems to be a lot cleaner. The merge of the earlier one to 'next' has been reverted. * sb/submodule-parallel-fetch: submodules: allow parallel fetching, add tests and documentation fetch_populated_submodules: use new parallel job processing run-command: add an asynchronous parallel child processor sigchain: add command to pop all common signals strbuf: add strbuf_read_once to read without blocking xread: poll on non blocking fds submodule.c: write "Fetching submodule " to stderr --- 187c0d3d9e63f7d84d7055372f07bedb52849f06 diff --combined submodule.h index ddff512109,cbc000304e..e06eaa5ebb --- a/submodule.h +++ b/submodule.h @@@ -5,7 -5,6 +5,7 @@@ struct diff_options struct argv_array; enum { + RECURSE_SUBMODULES_CHECK = -4, RECURSE_SUBMODULES_ERROR = -3, RECURSE_SUBMODULES_NONE = -2, RECURSE_SUBMODULES_ON_DEMAND = -1, @@@ -32,7 -31,7 +32,7 @@@ void set_config_fetch_recurse_submodule void check_for_new_submodule_commits(unsigned char new_sha1[20]); int fetch_populated_submodules(const struct argv_array *options, const char *prefix, int command_line_option, - int quiet); + int quiet, int max_parallel_jobs); unsigned is_submodule_modified(const char *path, int ignore_untracked); int submodule_uses_gitfile(const char *path); int ok_to_remove_submodule(const char *path); diff --combined wrapper.c index c95e2906b8,1770efac8e..b43d437630 --- a/wrapper.c +++ b/wrapper.c @@@ -236,8 -236,24 +236,24 @@@ ssize_t xread(int fd, void *buf, size_ len = MAX_IO_SIZE; while (1) { nr = read(fd, buf, len); - if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) - continue; + 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); + } + } return nr; } } @@@ -601,6 -617,18 +617,6 @@@ int access_or_die(const char *path, in return ret; } -struct passwd *xgetpwuid_self(void) -{ - struct passwd *pw; - - errno = 0; - pw = getpwuid(getuid()); - if (!pw) - die(_("unable to look up current user in the passwd file: %s"), - errno ? strerror(errno) : _("no such user")); - return pw; -} - char *xgetcwd(void) { struct strbuf sb = STRBUF_INIT;