Gergely Nagy <alger...@madhouse-project.org> writes: > I'll add fork() error handling and the above change, retest & send an > updated patch.
Updated patch attached below. As you suggested, $processes and $max_procs are initialised to 1 now, and the process waiting was reworked. Waiting in the else branch had another bug: if we didn't fork, a package could be skipped (in every case where $max_procs > 2, one package would be skipped in the else branch). With the updated patch, if $max_procs > 1, we wait until there's a slot ready, and fork then. This way no package will get lost, and it's a better solution anyway. Seems to work fine now, with parallel=1, 2 and 4 aswell. The else branch also handles errors from fork(), but the error message could use some improvement (I'm terrible when it comes to error messages). -- |8]
>From 3a2acbce4e606ac60f4eb116ecb981a31257d0a8 Mon Sep 17 00:00:00 2001 From: Gergely Nagy <alger...@madhouse-project.org> Date: Sun, 17 Jul 2011 20:48:05 +0200 Subject: [PATCH] dh_builddeb: support for parallel builds of debs Implement support for parallel deb builds, when DEB_BUILD_OPTIONS has parallels=N - limiting the number of forked processes to N. Requested-By: Kari Pahula <k...@debian.org> Signed-Off-By: Gergely Nagy <alger...@madhouse-project.org> --- dh_builddeb | 59 ++++++++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 42 insertions(+), 17 deletions(-) diff --git a/dh_builddeb b/dh_builddeb index b15c943..26e1274 100755 --- a/dh_builddeb +++ b/dh_builddeb @@ -63,30 +63,55 @@ else { $dh{FILENAME}="/$dh{FILENAME}"; } +my $processes=1; +my $max_procs=1; +if (defined $ENV{DEB_BUILD_OPTIONS} && $ENV{DEB_BUILD_OPTIONS}=~/parallel=(\d+)/) { + $max_procs=$1; +} + foreach my $package (@{$dh{DOPACKAGES}}) { - my $tmp=tmpdir($package); - if (exists $ENV{DH_ALWAYS_EXCLUDE} && length $ENV{DH_ALWAYS_EXCLUDE}) { - if (! compat(5)) { - complex_doit("find $tmp $dh{EXCLUDE_FIND} | xargs rm -rf"); + my $pid=0; + + if ($max_procs > 1) { + while ($processes > $max_procs) { + wait; + $processes--; + } + $pid=fork(); + } + + if ($pid == 0) { + my $tmp=tmpdir($package); + if (exists $ENV{DH_ALWAYS_EXCLUDE} && length $ENV{DH_ALWAYS_EXCLUDE}) { + if (! compat(5)) { + complex_doit("find $tmp $dh{EXCLUDE_FIND} | xargs rm -rf"); + } + else { + # Old broken code here for compatibility. Does not + # remove everything. + complex_doit("find $tmp -name $_ | xargs rm -rf") + foreach split(":", $ENV{DH_ALWAYS_EXCLUDE}); + } + } + if (! is_udeb($package)) { + doit("dpkg-deb", @{$dh{U_PARAMS}}, "--build", $tmp, $dh{DESTDIR}.$dh{FILENAME}); } else { - # Old broken code here for compatibility. Does not - # remove everything. - complex_doit("find $tmp -name $_ | xargs rm -rf") - foreach split(":", $ENV{DH_ALWAYS_EXCLUDE}); + my $filename=$dh{FILENAME}; + if (! $filename) { + $filename="/".udeb_filename($package); + } + doit("dpkg-deb", @{$dh{U_PARAMS}}, "--build", $tmp, $dh{DESTDIR}.$filename); } - } - if (! is_udeb($package)) { - doit("dpkg-deb", @{$dh{U_PARAMS}}, "--build", $tmp, $dh{DESTDIR}.$dh{FILENAME}); - } - else { - my $filename=$dh{FILENAME}; - if (! $filename) { - $filename="/".udeb_filename($package); + exit (0) if ($max_procs > 1); + } else { + if (!defined $pid) { + error("fork failed!"); } - doit("dpkg-deb", @{$dh{U_PARAMS}}, "--build", $tmp, $dh{DESTDIR}.$filename); + $processes++; } } +while (($max_procs > 0) && (wait != -1)) {} =head1 SEE ALSO -- 1.7.2.5