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 %childProcesses;
|
||||||
my %finishedOperations;
|
my %finishedOperations;
|
||||||
|
|
||||||
my $childHandler = sub {
|
my $HANDLE_BLAME_WORKERS_SUB = sub {
|
||||||
# don't change $! and $? outside handler
|
# don't change $! and $? outside handler
|
||||||
local ($!, $?);
|
local ($!, $?);
|
||||||
while ( (my $pid = waitpid(-1, WNOHANG)) > 0 ) {
|
while ( (my $pid = waitpid(-1, WNOHANG)) > 0 ) {
|
||||||
|
@ -155,7 +155,6 @@ my $childHandler = sub {
|
||||||
delete $childProcesses{$pid};
|
delete $childProcesses{$pid};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
# $SIG{CHLD} = $childHandler;
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
sub StartChildLog($$) {
|
sub StartChildLog($$) {
|
||||||
my($operation, $pid) = @_;
|
my($operation, $pid) = @_;
|
||||||
|
@ -220,23 +219,46 @@ sub RunCentralCommitMode($) {
|
||||||
$files{$file} = $commitId if not defined $files{$file};
|
$files{$file} = $commitId if not defined $files{$file};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$SIG{CHLD} = $HANDLE_BLAME_WORKERS_SUB;
|
||||||
foreach my $file (keys %files) {
|
foreach my $file (keys %files) {
|
||||||
my($vv, $path, $filename) = File::Spec->splitpath($file);
|
my($vv, $path, $filename) = File::Spec->splitpath($file);
|
||||||
$path = File::Spec->catfile($centralOutputDir, $path);
|
$path = File::Spec->catfile($centralOutputDir, $path);
|
||||||
make_path($path, 0750);
|
make_path($path, 0750);
|
||||||
my(@blameData);
|
my $remainingCount = scalar(keys %childProcesses);
|
||||||
eval {
|
while ($remainingCount >= $FORK_LIMIT) {
|
||||||
@blameData = $gitRepository->run('blame', '-w', '-f', '-n', '-l', @ADDITIONAL_BLAME_OPTS,
|
print STDERR "Sleep a bit while $remainingCount children going for these commits ",
|
||||||
$centralCommitId, '--', $file);
|
join(", ", sort values %childProcesses), "\n" if $VERBOSE;
|
||||||
};
|
sleep 10;
|
||||||
my $err = $@;
|
$remainingCount = scalar(keys %childProcesses);
|
||||||
if (defined $err and $err =~ /fatal.*no\s+such\s+path/) {
|
}
|
||||||
# ignore this file; it isn't present anymore in the central commit.
|
my $forkCount = scalar(keys %childProcesses) + 1;
|
||||||
} elsif (defined $err and $err !~ /^\s*$/) {
|
my $pid = fork();
|
||||||
die "unrecoverable git blame error: $err";
|
die "cannot fork: $!" unless defined $pid;
|
||||||
} else {
|
if ($pid == 0) { # The new child process is here
|
||||||
my $f = File::Spec->catfile($path, $filename);
|
$SIG{CHLD} = 'DEFAULT';
|
||||||
GitBlameDataToFile($f, \@blameData);
|
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);
|
||||||
|
};
|
||||||
|
my $err = $@;
|
||||||
|
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*$/) {
|
||||||
|
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