[debhelper-devel] [debhelper] 04/08: Dh_Lib: Add on_pkgs_in_parallel

Niels Thykier nthykier at moszumanska.debian.org
Tue Jun 13 20:33:05 UTC 2017


This is an automated email from the git hooks/post-receive script.

nthykier pushed a commit to branch master
in repository debhelper.

commit 9165ecdcacc70aee5d7b53ca607ad93de2ae7122
Author: Niels Thykier <niels at thykier.net>
Date:   Sun Jun 4 18:58:42 2017 +0000

    Dh_Lib: Add on_pkgs_in_parallel
    
    Signed-off-by: Niels Thykier <niels at thykier.net>
    
    fixup! Dh_Lib: Add on_each_pkg_in_parallel
---
 Debian/Debhelper/Dh_Lib.pm | 55 ++++++++++++++++++++++++++++++++++++++++++++++
 doc/PROGRAMMING            | 18 +++++++++++++++
 2 files changed, 73 insertions(+)

diff --git a/Debian/Debhelper/Dh_Lib.pm b/Debian/Debhelper/Dh_Lib.pm
index 6de5d42..ac00fb0 100644
--- a/Debian/Debhelper/Dh_Lib.pm
+++ b/Debian/Debhelper/Dh_Lib.pm
@@ -52,11 +52,14 @@ use vars qw(@EXPORT %dh);
 	    &restore_file_on_clean &restore_all_files
 	    &open_gz &reset_perm_and_owner &deprecated_functionality
 	    &log_installed_files &buildarch &rename_path
+	    &on_each_pkg_in_parallel
 );
 
 # The Makefile changes this if debhelper is installed in a PREFIX.
 my $prefix="/usr";
 
+my $MAX_PROCS = get_buildoption("parallel") || 1;
+
 sub init {
 	my %params=@_;
 
@@ -1599,6 +1602,58 @@ sub log_installed_files {
 	return 1;
 }
 
+sub on_pkgs_in_parallel(&) {
+	my ($code) = @_;
+	my @pkgs = @{$dh{DOPACKAGES}};
+	my %pids;
+	my $parallel = $MAX_PROCS;
+	my $count_per_proc = int(scalar(@pkgs) / $parallel);
+	my $exit = 0;
+	if ($count_per_proc < 1) {
+		$count_per_proc = 1;
+		if (@pkgs > 3) {
+			# Forking has a considerable overhead, so bulk the number
+			# a bit.  We do not do this unconditionally, because we
+			# want parallel issues (if any) to appear already with 2
+			# packages and two procs (because people are lazy when
+			# testing).
+			#
+			# Same reason for also unconditionally forking with 1 pkg
+			# in 1 proc.
+			$count_per_proc = 2;
+		}
+	}
+	# Assertion, $count_per_proc * $parallel >= scalar(@pkgs)
+	while (@pkgs) {
+		my @batch = splice(@pkgs, 0, $count_per_proc);
+		my $pid = fork() // error("fork: $!");
+		if (not $pid) {
+			eval {
+				$code->(@batch);
+			};
+			if (my $err = $@) {
+				$err =~ s/\n$//;
+				print STDERR "$err\n";
+				exit(2);
+			}
+			exit(0);
+		}
+		$pids{$pid} = 1;
+	}
+	while (%pids) {
+		my $pid = wait;
+		error("wait() failed: $!") if $pid == -1;
+		delete($pids{$pid});
+		if ($? != 0) {
+			$exit = 1;
+		}
+	}
+	if ($exit) {
+		error("Aborting due to earlier error");
+	}
+	return;
+}
+
 1
 
 # Local Variables:
diff --git a/doc/PROGRAMMING b/doc/PROGRAMMING
index 0236280..1827811 100644
--- a/doc/PROGRAMMING
+++ b/doc/PROGRAMMING
@@ -357,6 +357,24 @@ log_installed_files($package, @paths)
 	(e.g. avoid "foo/../bar" or "foo/./bar")
 	If a directory is listed, it and all paths recursively beneath is
 	also considered installed.
+on_pkgs_in_parallel($code) - prototype: (&)
+	Splits all the packages in $dh{DOPACKAGES} into a number of groups
+	based on the max parallel (as decided by DEB_BUILD_OPTIONS)
+	A subprocess is forked for each group (minimum 1 process will be
+	forked) and each subprocess will be added a group of packages
+	to process.  Each group is passed to the $code sub, which will
+	then process it and return normally on success.
+	Example:
+		on_pkgs_in_parallel {
+			for my $package (@_) {
+				my $tmp=tmpdir($package);
+				my $pkgfile = pkgfile($package, 'foo');
+				...;
+			}
+		 }
+
+	Keep in mind that the sub will always be run in a subprocess,
+	so it cannot update global state.
 
 Sequence Addons:
 ---------------

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debhelper/debhelper.git




More information about the debhelper-devel mailing list