]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/Qspawn.pm
qspawn: fix process finalization for generic PSGI server
[public-inbox.git] / lib / PublicInbox / Qspawn.pm
index cea34fc3325409078c18417aa470ef70cb78410f..297a284fd4c47deb224f9f7bbc01640fc9d91c31 100644 (file)
@@ -187,7 +187,7 @@ sub event_step {
        my ($self, $err) = @_; # $err: $!
        warn "psgi_{return,qx} $err" if defined($err);
        finish($self);
-       my ($fh, $qx_fh) = delete(@$self{qw(fh qx_fh)});
+       my ($fh, $qx_fh) = delete(@$self{qw(qfh qx_fh)});
        $fh->close if $fh; # async-only (psgi_return)
 }
 
@@ -225,31 +225,37 @@ sub psgi_return_init_cb {
        my ($self) = @_;
        my $r = rd_hdr($self) or return;
        my $env = $self->{psgi_env};
-       my $filter = delete $env->{'qspawn.filter'} //
-               PublicInbox::GzipFilter::qsp_maybe($r->[1], $env);
+       my $filter = delete($env->{'qspawn.filter'}) // (ref($r) eq 'ARRAY' ?
+               PublicInbox::GzipFilter::qsp_maybe($r->[1], $env) : undef);
 
        my $wcb = delete $env->{'qspawn.wcb'};
        my $async = delete $self->{async}; # PublicInbox::HTTPD::Async
-       if (scalar(@$r) == 3) { # error
+       if (ref($r) ne 'ARRAY' || scalar(@$r) == 3) { # error
                if ($async) { # calls rpipe->close && ->event_step
                        $async->close; # PublicInbox::HTTPD::Async::close
-               } else {
-                       $self->{rpipe}->close;
+               } else { # generic PSGI:
+                       delete($self->{rpipe})->close;
                        event_step($self);
+                       waitpid_err($self);
                }
-               $wcb->($r);
+               if (ref($r) eq 'ARRAY') { # error
+                       $wcb->($r)
+               } elsif (ref($r) eq 'CODE') { # chain another command
+                       $r->($wcb)
+               }
+               # else do nothing
        } elsif ($async) {
                # done reading headers, handoff to read body
                my $fh = $wcb->($r); # scalar @$r == 2
                $fh = $filter->attach($fh) if $filter;
-               $self->{fh} = $fh;
+               $self->{qfh} = $fh;
                $async->async_pass($env->{'psgix.io'}, $fh,
                                        delete($self->{hdr_buf}));
        } else { # for synchronous PSGI servers
                require PublicInbox::GetlineBody;
+               my $buf = delete $self->{hdr_buf};
                $r->[2] = PublicInbox::GetlineBody->new($self->{rpipe},
-                                       \&event_step, $self,
-                                       ${$self->{hdr_buf}}, $filter);
+                                       \&event_step, $self, $$buf, $filter);
                $wcb->($r);
        }
 }