lib/PublicInbox/GitHTTPBackend.pm | 19 ++++++++++++++----- lib/PublicInbox/HTTP.pm | 9 +++++++++ diff --git a/lib/PublicInbox/GitHTTPBackend.pm b/lib/PublicInbox/GitHTTPBackend.pm index 30efa839ac3abb2cd0b8692478c29c8839df13dd..4b3969346acefda27f49ffd47c5f0b26db49a1c6 100644 --- a/lib/PublicInbox/GitHTTPBackend.pm +++ b/lib/PublicInbox/GitHTTPBackend.pm @@ -95,6 +95,7 @@ last if (!defined($r) || $r <= 0); $len -= $r; $fh->write($buf); } + die "$f truncated with $len bytes remaining\n" if $len; $fh->close; } } @@ -191,14 +192,21 @@ $fh->close; $fh = undef; } if ($rpipe) { - $rpipe->close; # _may_ be Danga::Socket::close + # _may_ be Danga::Socket::close via + # PublicInbox::HTTPD::Async::close: + $rpipe->close; $rpipe = undef; $nr_running--; } - if (defined $pid && $pid != waitpid($pid, 0)) { - $err->print("git http-backend ($git_dir): $?\n"); - } else { - $pid = undef; + if (defined $pid) { + my $e = $pid == waitpid($pid, 0) ? + $? : "PID:$pid still running?"; + if ($e) { + $err->print("http-backend ($git_dir): $e\n"); + if (my $io = $env->{'psgix.io'}) { + $io->close; + } + } } return unless $res; my $dumb = serve_dumb($cgi, $git, $path); @@ -245,6 +253,7 @@ $buf = ''; } # else { keep reading ... } }; if (my $async = $env->{'pi-httpd.async'}) { + # $async is PublicInbox::HTTPD::Async->new($rpipe, $cb) $rpipe = $async->($rpipe, $cb); sub { ($res) = @_ } # let Danga::Socket handle the rest. } else { # synchronous loop for other PSGI servers diff --git a/lib/PublicInbox/HTTP.pm b/lib/PublicInbox/HTTP.pm index c7fb954ebd6c0f0b472dce57bf1a07601a01866c..973da3418c76282e3d38989c0e04f1130c4349f1 100644 --- a/lib/PublicInbox/HTTP.pm +++ b/lib/PublicInbox/HTTP.pm @@ -135,6 +135,9 @@ sysseek($env->{'psgi.input'}, 0, SEEK_SET) or die "BUG: psgi.input seek failed: $!"; + # note: NOT $self->{sock}, we want our close (+ Danga::Socket::close), + # to do proper cleanup: + $env->{'psgix.io'} = $self; # only for ->close my $res = Plack::Util::run_app($self->{httpd}->{app}, $env); eval { if (ref($res) eq 'CODE') { @@ -370,6 +373,12 @@ # callbacks for Danga::Socket sub event_hup { $_[0]->close } sub event_err { $_[0]->close } + +sub close { + my $self = shift; + $self->{env} = undef; + $self->SUPER::close(@_); +} sub write ($$) : method { my PublicInbox::HTTP $self = $_[0];