Index: dirvish-1.2.1/dirvish-runall.pl =================================================================== --- dirvish-1.2.1.orig/dirvish-runall.pl +++ dirvish-1.2.1/dirvish-runall.pl @@ -28,6 +28,7 @@ $VERSION =~ s/_/./g; use Time::ParseDate; use POSIX qw(strftime); +use POSIX ":sys_wait_h"; use Getopt::Long; sub loadconfig; @@ -94,22 +95,63 @@ else } $$Config{Dirvish} ||= 'dirvish'; +$$Config{concurrent} ||= '1'; +@pidList = (); + $$Options{'no-run'} and $$Options{quiet} = 0; $errors = 0; for $sched (@{$$Config{Runall}}) { + # Wait until we have a free slot + until (scalar(@pidList) < int($$Config{concurrent})) { + @pidList2 = (); + for $pid (@pidList) { + $wait_result = waitpid($pid, WNOHANG); + if ($wait_result > 0) { + # Increment the error counter if dirvish failed + $? < 0 || $? / 256 and ++$errors; + } else { + # Keep PID + push(@pidList2, $pid); + } + } + # Put all unsuccessful PIDs back in pidList + @pidList = @pidList2; + sleep(1); + } + + # Spawn Child ($vault, $itime) = split(/\s+/, $sched); $cmd = "$$Config{Dirvish} --vault $vault"; $itime and $cmd .= qq[ --image-time "$itime"]; $$Options{quiet} or printf "%s %s\n", strftime('%H:%M:%S', localtime), $cmd; $$Options{'no-run'} and next; - $status = system($cmd); - $status < 0 || $status / 256 and ++$errors; - + $pid = fork(); + if ($pid > 0) { + # Parent thread, register child pid + push(@pidList, $pid); + } elsif ($pid == -1) { + # Failed fork + print "Fork failed!\n"; + } else { + # pid == 0, child thread + exec($cmd) || die "child exit"; + } +} + +# Wait for remaining dirvish processes +for $pid (@pidList) { + # Wait forever this time + $wait_result = waitpid($pid, 0); + if ($wait_result == -1 or $wait_result == $pid) { + # Increment the error counter if dirvish failed + $? < 0 || $? / 256 and ++$errors; + } } + $$Options{quiet} or printf "%s %s\n", strftime('%H:%M:%S', localtime), 'done';