| 1889 | } |
| 1890 | |
| 1891 | void run_processes_parallel(const struct run_process_parallel_opts *opts) |
| 1892 | { |
| 1893 | int i, code; |
| 1894 | int timeout = 100; |
| 1895 | int spawn_cap = 4; |
| 1896 | struct parallel_processes_for_signal pp_sig; |
| 1897 | struct parallel_processes pp = { |
| 1898 | .buffered_output = STRBUF_INIT, |
| 1899 | }; |
| 1900 | /* options */ |
| 1901 | const char *tr2_category = opts->tr2_category; |
| 1902 | const char *tr2_label = opts->tr2_label; |
| 1903 | const int do_trace2 = tr2_category && tr2_label; |
| 1904 | |
| 1905 | if (do_trace2) |
| 1906 | trace2_region_enter_printf(tr2_category, tr2_label, NULL, |
| 1907 | "max:%"PRIuMAX, |
| 1908 | (uintmax_t)opts->processes); |
| 1909 | |
| 1910 | pp_init(&pp, opts, &pp_sig); |
| 1911 | |
| 1912 | /* |
| 1913 | * Child tasks might receive input via stdin, terminating early (or not), so |
| 1914 | * ignore the default SIGPIPE which gets handled by each feed_pipe_fn which |
| 1915 | * actually writes the data to children stdin fds. |
| 1916 | * |
| 1917 | * This _must_ come after pp_init(), because it installs its own |
| 1918 | * SIGPIPE handler (to cleanup children), and we want to supersede |
| 1919 | * that. |
| 1920 | */ |
| 1921 | sigchain_push(SIGPIPE, SIG_IGN); |
| 1922 | |
| 1923 | while (1) { |
| 1924 | for (i = 0; |
| 1925 | i < spawn_cap && !pp.shutdown && |
| 1926 | pp.nr_processes < opts->processes; |
| 1927 | i++) { |
| 1928 | code = pp_start_one(&pp, opts); |
| 1929 | if (!code) |
| 1930 | continue; |
| 1931 | if (code < 0) { |
| 1932 | pp.shutdown = 1; |
| 1933 | kill_children(&pp, opts, -code); |
| 1934 | } |
| 1935 | break; |
| 1936 | } |
| 1937 | if (!pp.nr_processes) |
| 1938 | break; |
| 1939 | pp_handle_child_IO(&pp, opts, timeout); |
| 1940 | code = pp_collect_finished(&pp, opts); |
| 1941 | if (code) { |
| 1942 | pp.shutdown = 1; |
| 1943 | if (code < 0) |
| 1944 | kill_children(&pp, opts,-code); |
| 1945 | } |
| 1946 | } |
| 1947 | |
| 1948 | sigchain_pop(SIGPIPE); |