Our tests scream at this patch, it's just to show what I plan to do.
Essentially moving the content of the loop into the get_next_task
callback from the run_processes_parallel.

Signed-off-by: Stefan Beller <sbel...@google.com>
---
 builtin/submodule--helper.c | 181 +++++++++++++++++++++++++++++---------------
 1 file changed, 119 insertions(+), 62 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index fa8c008..c66aa53 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -289,65 +289,40 @@ static void fill_clone_command(struct child_process *cp, 
int quiet,
                argv_array_push(&cp->args, depth);
 }
 
-static int module_list_or_clone(int argc, const char **argv, const char 
*prefix)
-{
-       int i;
-       int quiet;
-       char *reference = NULL, *depth = NULL;
-       char *update = NULL;
+struct submodule_list_or_clone {
        struct pathspec pathspec;
-       struct module_list list = MODULE_LIST_INIT;
-       struct string_list projectlines = STRING_LIST_INIT_DUP;
-       struct string_list_item *item;
-
-       struct option module_list_options[] = {
-               OPT_STRING(0, "prefix", &prefix,
-                          N_("path"),
-                          N_("alternative anchor for relative paths")),
-               OPT_STRING(0, "update", &update,
-                          N_("string"),
-                          N_("update command for submodules")),
-               OPT_STRING(0, "reference", &reference, "<repository>",
-                       N_("Use the local reference repository "
-                          "instead of a full clone")),
-               OPT_STRING(0, "depth", &depth, "<depth>",
-                       N_("Create a shallow clone truncated to the "
-                          "specified number of revisions")),
-               OPT__QUIET(&quiet, N_("do't print cloning progress")),
-               OPT_END()
-       };
-
-       const char *const git_submodule_helper_usage[] = {
-               N_("git submodule--helper list [--prefix=<path>] [<path>...]"),
-               NULL
-       };
-
-       argc = parse_options(argc, argv, prefix, module_list_options,
-                            git_submodule_helper_usage, 0);
-
-       if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0) {
-               printf("#unmatched\n");
-               return 1;
-       }
+       struct module_list list;
+       struct string_list projectlines;
+       int count;
+       int quiet;
+       char *reference;
+       char *depth;
+       char *update;
+       char *env_prefix;
+       const char *prefix;
+       int print_unmatched;
+};
 
-       gitmodules_config();
-       /* Overlay the parsed .gitmodules file with .git/config */
-       git_config(git_submodule_config, NULL);
+static int get_next_task(void **pp_task_cb,
+                        struct child_process *cp,
+                        struct strbuf *err,
+                        void *pp_cb)
+{
+       struct submodule_list_or_clone *pp = pp_cb;
 
-       for (i = 0; i < list.nr; i++) {
+       for (; pp->count < pp->list.nr; pp->count++) {
                const struct submodule *sub = NULL;
                const char *displaypath = NULL;
-               const struct cache_entry *ce = list.entries[i];
+               const struct cache_entry *ce = pp->list.entries[pp->count];
                struct strbuf sb = STRBUF_INIT;
                const char *update_module = NULL;
                const char *url = NULL;
                int just_cloned = 0;
 
-               char *env_prefix = getenv("prefix");
                if (ce_stage(ce)) {
-                       if (env_prefix)
+                       if (pp->env_prefix)
                                fprintf(stderr, "Skipping unmerged submodule 
%s/%s\n",
-                                       env_prefix, ce->name);
+                                       pp->env_prefix, ce->name);
                        else
                                fprintf(stderr, "Skipping unmerged submodule 
%s\n",
                                        ce->name);
@@ -355,13 +330,13 @@ static int module_list_or_clone(int argc, const char 
**argv, const char *prefix)
                }
 
                sub = submodule_from_path(null_sha1, ce->name);
-               if (env_prefix)
-                       displaypath = relative_path(env_prefix, ce->name, &sb);
+               if (pp->env_prefix)
+                       displaypath = relative_path(pp->env_prefix, ce->name, 
&sb);
                else
                        displaypath = ce->name;
 
-               if (update)
-                       update_module = update;
+               if (pp->update)
+                       update_module = pp->update;
                if (!update_module)
                        update_module = sub->update;
                if (!update_module)
@@ -385,7 +360,7 @@ static int module_list_or_clone(int argc, const char 
**argv, const char *prefix)
                         * Only mention uninitialized submodules when its
                         * path have been specified
                         */
-                       if (pathspec.nr)
+                       if (pp->pathspec.nr)
                                fprintf(stderr, _("Submodule path '%s' not 
initialized\n"
                                        "Maybe you want to use 'update 
--init'?"), displaypath);
                        continue;
@@ -396,23 +371,105 @@ static int module_list_or_clone(int argc, const char 
**argv, const char *prefix)
                just_cloned = !file_exists(sb.buf);
 
                if (just_cloned) {
-                       struct child_process cp = CHILD_PROCESS_INIT;
-                       fill_clone_command(&cp, quiet, prefix, ce->name,
-                                          sub->name, url, reference, depth);
-
-                       if (run_command(&cp)) {
-                               printf("#unmatched\n");
-                               return 1;
-                       }
+                       fill_clone_command(cp, pp->quiet, pp->prefix, ce->name,
+                                          sub->name, url, pp->reference, 
pp->depth);
+                       return 1;
                }
                strbuf_reset(&sb);
                strbuf_addf(&sb, "%06o %s %d %d\t%s\n", ce->ce_mode,
                                sha1_to_hex(ce->sha1), ce_stage(ce),
                                just_cloned, ce->name);
-               string_list_append(&projectlines, sb.buf);
+               string_list_append(&pp->projectlines, sb.buf);
+       }
+       return 0;
+}
+
+static int start_failure(struct child_process *cp,
+                        struct strbuf *err,
+                        void *pp_cb,
+                        void *pp_task_cb)
+{
+       struct submodule_list_or_clone *pp = pp_cb;
+
+       pp->print_unmatched = 1;
+
+       return 1;
+}
+
+static int task_finished(int result,
+                        struct child_process *cp,
+                        struct strbuf *err,
+                        void *pp_cb,
+                        void *pp_task_cb)
+{
+       struct submodule_list_or_clone *pp = pp_cb;
+
+       if (!result)
+               return 0;
+       else {
+               pp->print_unmatched = 1;
+               return 1;
+       }
+}
+
+static int module_list_or_clone(int argc, const char **argv, const char 
*prefix)
+{
+       struct submodule_list_or_clone pp;
+       struct string_list_item *item;
+
+       struct option module_list_options[] = {
+               OPT_STRING(0, "prefix", &pp.prefix,
+                          N_("path"),
+                          N_("alternative anchor for relative paths")),
+               OPT_STRING(0, "update", &pp.update,
+                          N_("string"),
+                          N_("update command for submodules")),
+               OPT_STRING(0, "reference", &pp.reference, "<repository>",
+                       N_("Use the local reference repository "
+                          "instead of a full clone")),
+               OPT_STRING(0, "depth", &pp.depth, "<depth>",
+                       N_("Create a shallow clone truncated to the "
+                          "specified number of revisions")),
+               OPT__QUIET(&pp.quiet, N_("do't print cloning progress")),
+               OPT_END()
+       };
+
+       const char *const git_submodule_helper_usage[] = {
+               N_("git submodule--helper list [--prefix=<path>] [<path>...]"),
+               NULL
+       };
+
+       pp.prefix = NULL;
+       pp.list.entries = NULL;
+       pp.list.alloc = 0;
+       pp.list.nr = 0;
+       string_list_init(&pp.projectlines, 1);
+       pp.count = 0;
+       pp.reference = NULL;
+       pp.depth = NULL;
+       pp.update = NULL;
+       pp.env_prefix = getenv("prefix");
+       pp.print_unmatched = 0;
+
+       argc = parse_options(argc, argv, prefix, module_list_options,
+                            git_submodule_helper_usage, 0);
+
+       if (module_list_compute(argc, argv, pp.prefix, &pp.pathspec, &pp.list) 
< 0) {
+               printf("#unmatched\n");
+               return 1;
+       }
+
+       gitmodules_config();
+       /* Overlay the parsed .gitmodules file with .git/config */
+       git_config(git_submodule_config, NULL);
+
+       run_processes_parallel(1, get_next_task, start_failure, task_finished, 
&pp);
+       if (pp.print_unmatched) {
+               printf("#unmatched\n");
+               return 1;
        }
 
-       for_each_string_list_item(item, &projectlines) {
+       for_each_string_list_item(item, &pp.projectlines) {
                utf8_fprintf(stdout, "%s", item->string);
        }
        return 0;
-- 
2.5.0.277.gfdc362b.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to