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…
	
	Add table
		
		Reference in a new issue
	
	 Bradley M. Kuhn
						Bradley M. Kuhn