Working version of forking central commit.
Note that due to the fact that Git::Repository calls System::Command, you have to be careful about when you install the child signal handler. You only want it in the parent, after the parent has done its operations with Git commands, and note that the child must also disable the handler.
This commit is contained in:
parent
1cb64afb40
commit
675cd0a98b
1 changed files with 37 additions and 15 deletions
|
@ -143,7 +143,7 @@ while (my $line = <STDIN>) {
|
|||
my %childProcesses;
|
||||
my %finishedOperations;
|
||||
|
||||
my $childHandler = sub {
|
||||
my $HANDLE_BLAME_WORKERS_SUB = sub {
|
||||
# don't change $! and $? outside handler
|
||||
local ($!, $?);
|
||||
while ( (my $pid = waitpid(-1, WNOHANG)) > 0 ) {
|
||||
|
@ -155,7 +155,6 @@ my $childHandler = sub {
|
|||
delete $childProcesses{$pid};
|
||||
}
|
||||
};
|
||||
# $SIG{CHLD} = $childHandler;
|
||||
##############################################################################
|
||||
sub StartChildLog($$) {
|
||||
my($operation, $pid) = @_;
|
||||
|
@ -220,11 +219,28 @@ sub RunCentralCommitMode($) {
|
|||
$files{$file} = $commitId if not defined $files{$file};
|
||||
}
|
||||
}
|
||||
$SIG{CHLD} = $HANDLE_BLAME_WORKERS_SUB;
|
||||
foreach my $file (keys %files) {
|
||||
my($vv, $path, $filename) = File::Spec->splitpath($file);
|
||||
$path = File::Spec->catfile($centralOutputDir, $path);
|
||||
make_path($path, 0750);
|
||||
my $remainingCount = scalar(keys %childProcesses);
|
||||
while ($remainingCount >= $FORK_LIMIT) {
|
||||
print STDERR "Sleep a bit while $remainingCount children going for these commits ",
|
||||
join(", ", sort values %childProcesses), "\n" if $VERBOSE;
|
||||
sleep 10;
|
||||
$remainingCount = scalar(keys %childProcesses);
|
||||
}
|
||||
my $forkCount = scalar(keys %childProcesses) + 1;
|
||||
my $pid = fork();
|
||||
die "cannot fork: $!" unless defined $pid;
|
||||
if ($pid == 0) { # The new child process is here
|
||||
$SIG{CHLD} = 'DEFAULT';
|
||||
my $logFH = StartChildLog($filename, $$);
|
||||
$0 = "$path/$filename git blame subprocess";
|
||||
my(@blameData);
|
||||
print $logFH "running: git",
|
||||
'blame', '-w', '-f', '-n', '-l', @ADDITIONAL_BLAME_OPTS, $centralCommitId, '--', $file, "\n";
|
||||
eval {
|
||||
@blameData = $gitRepository->run('blame', '-w', '-f', '-n', '-l', @ADDITIONAL_BLAME_OPTS,
|
||||
$centralCommitId, '--', $file);
|
||||
|
@ -233,11 +249,17 @@ sub RunCentralCommitMode($) {
|
|||
if (defined $err and $err =~ /fatal.*no\s+such\s+path/) {
|
||||
# ignore this file; it isn't present anymore in the central commit.
|
||||
} elsif (defined $err and $err !~ /^\s*$/) {
|
||||
die "unrecoverable git blame error: $err";
|
||||
print $logFH "unrecoverable git blame error: $err";
|
||||
} else {
|
||||
my $f = File::Spec->catfile($path, $filename);
|
||||
GitBlameDataToFile($f, \@blameData);
|
||||
}
|
||||
EndChildLog($logFH, $filename, $$);
|
||||
exit 0;
|
||||
} else { # The parent is here
|
||||
$childProcesses{$pid} = $file;
|
||||
print STDERR "Launched $forkCount child to handle $filename\n" if $VERBOSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
##############################################################################
|
||||
|
|
Loading…
Reference in a new issue