about summary refs log tree commit
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2019-09-14 09:35:39 +0000
committerEric Wong <e@80x24.org>2019-09-14 09:36:07 +0000
commitaea0a8d8bf9bf26898c811bf28f023d968c39de3 (patch)
tree737dbf6d966645d52872ae7a4d6af53d7e19bcc7
parent500a3dad334601d928e20dd9d764fb117f65103d (diff)
downloadpublic-inbox-aea0a8d8bf9bf26898c811bf28f023d968c39de3.tar.gz
Rename the {cleanup} field to {end}, since it's similar
to END {} and is consistent with the variable in Qspawn.pm

And document how certain subs get called, since we have
many subs named "new" and "close".
-rw-r--r--lib/PublicInbox/HTTPD/Async.pm37
-rw-r--r--lib/PublicInbox/Qspawn.pm4
2 files changed, 29 insertions, 12 deletions
diff --git a/lib/PublicInbox/HTTPD/Async.pm b/lib/PublicInbox/HTTPD/Async.pm
index 8e8ece39..d5628ee8 100644
--- a/lib/PublicInbox/HTTPD/Async.pm
+++ b/lib/PublicInbox/HTTPD/Async.pm
@@ -10,26 +10,29 @@ package PublicInbox::HTTPD::Async;
 use strict;
 use warnings;
 use base qw(PublicInbox::DS);
-use fields qw(cb cleanup);
+use fields qw(cb end);
 use Errno qw(EAGAIN);
 use PublicInbox::Syscall qw(EPOLLIN EPOLLET);
 
+# This is called via: $env->{'pi-httpd.async'}->()
+# $io is a read-only pipe ($rpipe) for now, but may be a
+# bidirectional socket in the future.
 sub new {
-        my ($class, $io, $cb, $cleanup) = @_;
+        my ($class, $io, $cb, $end) = @_;
 
         # no $io? call $cb at the top of the next event loop to
         # avoid recursion:
         unless (defined($io)) {
                 PublicInbox::DS::requeue($cb);
-                die 'cleanup unsupported w/o $io' if $cleanup;
+                die '$end unsupported w/o $io' if $end;
                 return;
         }
 
         my $self = fields::new($class);
         IO::Handle::blocking($io, 0);
         $self->SUPER::new($io, EPOLLIN | EPOLLET);
-        $self->{cb} = $cb;
-        $self->{cleanup} = $cleanup;
+        $self->{cb} = $cb; # initial read callback, later replaced by main_cb
+        $self->{end} = $end; # like END {}, but only for this object
         $self;
 }
 
@@ -37,6 +40,8 @@ sub main_cb ($$) {
         my ($http, $fh) = @_;
         sub {
                 my ($self) = @_;
+                # $self->{sock} is a read pipe for git-http-backend or cgit
+                # and 65536 is the default Linux pipe size
                 my $r = sysread($self->{sock}, my $buf, 65536);
                 if ($r) {
                         $fh->write($buf); # may call $http->close
@@ -52,19 +57,28 @@ sub main_cb ($$) {
                 }
 
                 # Done! Error handling will happen in $fh->close
-                # called by the {cleanup} handler
+                # called by the {end} handler
                 delete $http->{forward};
-                $self->close;
+                $self->close; # queues ->{end} to be called
         }
 }
 
+# once this is called, all data we read is passed to the
+# to the PublicInbox::HTTP instance ($http) via $fh->write
 sub async_pass {
         my ($self, $http, $fh, $bref) = @_;
         # In case the client HTTP connection ($http) dies, it
         # will automatically close this ($self) object.
         $http->{forward} = $self;
+
+        # write anything we overread when we were reading headers
         $fh->write($$bref); # PublicInbox:HTTP::{chunked,identity}_wcb
-        $$bref = undef; # we're done with this
+
+        # we're done with this, free this memory up ASAP since the
+        # calls after this may use much memory:
+        $$bref = undef;
+
+        # replace the header read callback with the main one
         my $cb = $self->{cb} = main_cb($http, $fh);
         $cb->($self); # either hit EAGAIN or ->requeue to keep EPOLLET happy
 }
@@ -75,14 +89,15 @@ sub event_step {
         $cb->(@_);
 }
 
+# may be called as $forward->close in PublicInbox::HTTP or EOF (main_cb)
 sub close {
         my $self = $_[0];
         delete $self->{cb};
-        $self->SUPER::close;
+        $self->SUPER::close; # DS::close
 
         # we defer this to the next timer loop since close is deferred
-        if (my $cleanup = delete $self->{cleanup}) {
-                PublicInbox::DS::requeue($cleanup);
+        if (my $end = delete $self->{end}) {
+                PublicInbox::DS::requeue($end);
         }
 }
 
diff --git a/lib/PublicInbox/Qspawn.pm b/lib/PublicInbox/Qspawn.pm
index 76e48e81..294bf0a4 100644
--- a/lib/PublicInbox/Qspawn.pm
+++ b/lib/PublicInbox/Qspawn.pm
@@ -230,6 +230,7 @@ sub psgi_return {
 
         my $buf = '';
         my $rd_hdr = sub {
+                # typically used for reading CGI headers
                 # we must loop until EAGAIN for EPOLLET in HTTPD/Async.pm
                 # We also need to check EINTR for generic PSGI servers.
                 my $ret;
@@ -250,7 +251,7 @@ sub psgi_return {
 
         my $cb = sub {
                 my $r = $rd_hdr->() or return;
-                $rd_hdr = undef;
+                $rd_hdr = undef; # done reading headers
                 my $filter = delete $env->{'qspawn.filter'};
                 if (scalar(@$r) == 3) { # error
                         if ($async) {
@@ -261,6 +262,7 @@ sub psgi_return {
                         }
                         $wcb->($r);
                 } elsif ($async) {
+                        # done reading headers, handoff to read body
                         $fh = $wcb->($r); # scalar @$r == 2
                         $fh = filter_fh($fh, $filter) if $filter;
                         $async->async_pass($env->{'psgix.io'}, $fh, \$buf);