Git.pm: allow pipes to be closed prior to calling command_close_bidi_pipe
authorMichal Nazarewicz <mina86@mina86.com>
Tue, 12 Feb 2013 14:02:31 +0000 (15:02 +0100)
committerJunio C Hamano <gitster@pobox.com>
Tue, 12 Feb 2013 21:15:11 +0000 (13:15 -0800)
The command_close_bidi_pipe() function will insist on closing both
input and output pipes returned by command_bidi_pipe(). With this
change it is possible to close one of the pipes in advance and pass
undef as an argument.

Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
perl/Git.pm
index 2ccb95dc14a6ce6f7dbe906511c10295913e5a73..620e0f9e51100d0cba6593fb3c0236d79087f819 100644 (file)
@@ -426,12 +426,25 @@ sub command_bidi_pipe {
 currently it is simply the command name but in future the context might
 have more complicated structure.
 
+C<PIPE_IN> and C<PIPE_OUT> may be C<undef> if they have been closed prior to
+calling this function.  This may be useful in a query-response type of
+commands where caller first writes a query and later reads response, eg:
+
+       my ($pid, $in, $out, $ctx) = $r->command_bidi_pipe('cat-file --batch-check');
+       print $out "000000000\n";
+       close $out;
+       while (<$in>) { ... }
+       $r->command_close_bidi_pipe($pid, $in, undef, $ctx);
+
+This idiom may prevent potential dead locks caused by data sent to the output
+pipe not being flushed and thus not reaching the executed command.
+
 =cut
 
 sub command_close_bidi_pipe {
        local $?;
        my ($self, $pid, $in, $out, $ctx) = _maybe_self(@_);
-       _cmd_close($ctx, $in, $out);
+       _cmd_close($ctx, (grep { defined } ($in, $out)));
        waitpid $pid, 0;
        if ($? >> 8) {
                throw Git::Error::Command($ctx, $? >>8);