about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--lib/PublicInbox/Git.pm14
-rw-r--r--t/git.t21
2 files changed, 29 insertions, 6 deletions
diff --git a/lib/PublicInbox/Git.pm b/lib/PublicInbox/Git.pm
index 90595840..af3a5712 100644
--- a/lib/PublicInbox/Git.pm
+++ b/lib/PublicInbox/Git.pm
@@ -148,16 +148,18 @@ sub read_cat_in_full ($$$) {
 
 sub _cat_async_step ($$$) {
         my ($self, $inflight, $in) = @_;
-        my $cb = shift @$inflight or die 'BUG: inflight empty';
+        my $pair = shift @$inflight or die 'BUG: inflight empty';
+        my ($cb, $arg) = @$pair;
         local $/ = "\n";
         my $head = $in->getline;
-        return eval { $cb->(undef) } if $head =~ / missing$/;
+        $head =~ / missing$/ and return
+                eval { $cb->(undef, undef, undef, undef, $arg) };
 
         $head =~ /^([0-9a-f]{40}) (\S+) ([0-9]+)$/ or
                 fail($self, "Unexpected result from async git cat-file: $head");
         my ($oid_hex, $type, $size) = ($1, $2, $3 + 0);
         my $bref = read_cat_in_full($self, $in, $size);
-        eval { $cb->($bref, $oid_hex, $type, $size) };
+        eval { $cb->($bref, $oid_hex, $type, $size, $arg) };
 }
 
 sub cat_async_wait ($) {
@@ -319,15 +321,15 @@ sub cat_async_begin {
         $self->{inflight} = [];
 }
 
-sub cat_async ($$$) {
-        my ($self, $oid, $cb) = @_;
+sub cat_async ($$$;$) {
+        my ($self, $oid, $cb, $arg) = @_;
         my $inflight = $self->{inflight} or die 'BUG: not in async';
         if (scalar(@$inflight) >= MAX_INFLIGHT) {
                 _cat_async_step($self, $inflight, $self->{in});
         }
 
         $self->{out}->print($oid, "\n") or fail($self, "write error: $!");
-        push @$inflight, $cb;
+        push(@$inflight, [ $cb, $arg ]);
 }
 
 sub commit_title ($$) {
diff --git a/t/git.t b/t/git.t
index d4694f44..6cfadd08 100644
--- a/t/git.t
+++ b/t/git.t
@@ -33,6 +33,27 @@ use_ok 'PublicInbox::Git';
 
         is(${$gcf->cat_file($f)}, $$raw, 'not broken after failures');
         is(${$gcf->cat_file($f)}, $$raw, 'not broken after partial read');
+
+        my $oid = $x[0];
+        my $arg = { 'foo' => 'bar' };
+        my $res = [];
+        my $missing = [];
+        $gcf->cat_async_begin;
+        $gcf->cat_async($oid, sub {
+                my ($bref, $oid_hex, $type, $size, $arg) = @_;
+                $res = [ @_ ];
+        }, $arg);
+        $gcf->cat_async('non-existent', sub {
+                my ($bref, $oid_hex, $type, $size, $arg) = @_;
+                $missing = [ @_ ];
+        }, $arg);
+        $gcf->cat_async_wait;
+        my ($bref, $oid_hex, $type, $size, $arg_res) = @$res;
+        is_deeply([$oid_hex, $type, $size], \@x, 'got expected header');
+        is($arg_res, $arg, 'arg passed to cat_async');
+        is_deeply($raw, $bref, 'blob result matches');
+        is_deeply($missing, [ undef, undef, undef, undef, $arg],
+                'non-existent blob gives expected result');
 }
 
 if (1) {