diff options
author | Eric Wong <e@80x24.org> | 2022-10-04 19:12:38 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2022-10-05 21:15:28 +0000 |
commit | f35d722d38e571458fc413b9f0d7ddd788ec4b98 (patch) | |
tree | 42dc9931cc6c551475f13416fde00cad74ba2ee6 /lib/PublicInbox/GitAsyncCat.pm | |
parent | ef39974fec81e2f776390965b739a0b37f6a0646 (diff) | |
download | public-inbox-f35d722d38e571458fc413b9f0d7ddd788ec4b98.tar.gz |
These should be compatible with cgit results
Diffstat (limited to 'lib/PublicInbox/GitAsyncCat.pm')
-rw-r--r-- | lib/PublicInbox/GitAsyncCat.pm | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/lib/PublicInbox/GitAsyncCat.pm b/lib/PublicInbox/GitAsyncCat.pm index 613dbf7e..2e0725a6 100644 --- a/lib/PublicInbox/GitAsyncCat.pm +++ b/lib/PublicInbox/GitAsyncCat.pm @@ -1,14 +1,14 @@ -# Copyright (C) 2020-2021 all contributors <meta@public-inbox.org> +# Copyright (C) all contributors <meta@public-inbox.org> # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt> # # internal class used by PublicInbox::Git + PublicInbox::DS # This parses the output pipe of "git cat-file --batch" package PublicInbox::GitAsyncCat; -use strict; +use v5.12; use parent qw(PublicInbox::DS Exporter); use POSIX qw(WNOHANG); use PublicInbox::Syscall qw(EPOLLIN EPOLLET); -our @EXPORT = qw(ibx_async_cat ibx_async_prefetch); +our @EXPORT = qw(ibx_async_cat ibx_async_prefetch async_check); use PublicInbox::Git (); our $GCF2C; # singleton PublicInbox::Gcf2Client @@ -74,6 +74,18 @@ sub ibx_async_cat ($$$$) { } } +sub async_check ($$$$) { + my ($ibx, $oidish, $cb, $arg) = @_; + my $git = $ibx->{git} // $ibx->git; + $git->check_async($oidish, $cb, $arg); + $git->{async_chk} //= do { + my $self = bless { git => $git }, 'PublicInbox::GitAsyncCheck'; + $git->{in_c}->blocking(0); + $self->SUPER::new($git->{in_c}, EPOLLIN|EPOLLET); + \undef; # this is a true ref() + }; +} + # this is safe to call inside $cb, but not guaranteed to enqueue # returns true if successful, undef if not. For fairness, we only # prefetch if there's no in-flight requests. @@ -96,3 +108,34 @@ sub ibx_async_prefetch { } 1; +package PublicInbox::GitAsyncCheck; +use v5.12; +our @ISA = qw(PublicInbox::GitAsyncCat); +use POSIX qw(WNOHANG); +use PublicInbox::Syscall qw(EPOLLIN EPOLLET); + +sub event_step { + my ($self) = @_; + my $git = $self->{git} or return; + return $self->close if ($git->{in_c} // 0) != ($self->{sock} // 1); + my $inflight = $git->{inflight_c}; + if ($inflight && @$inflight) { + $git->check_async_step($inflight); + + # child death? + if (($git->{in_c} // 0) != ($self->{sock} // 1)) { + $self->close; + } elsif (@$inflight || exists $git->{rbuf_c}) { + # ok, more to do, requeue for fairness + $self->requeue; + } + } elsif ((my $pid = waitpid($git->{pid_c}, WNOHANG)) > 0) { + # May happen if the child process is killed by a BOFH + # (or segfaults) + delete $git->{pid_c}; + warn "E: git $pid exited with \$?=$?\n"; + $self->close; + } +} + +1; |