Clean termination of remote-helpers (was Re: [PATCH 2/2] Add a remote helper to interact with mediawiki (fetch & push))
- From
Matthieu Moy <matthieu.moy@grenoble-inp.fr>
- Date
- Aug 31, 2011, 12:33 UTC
- Message-ID
- <vpqd3flzrow.fsf_-_@bauges.imag.fr>
- In-Reply-To
- <1314378689-8997-2-git-send-email-Matthieu.Moy@imag.fr>
Matthieu Moy <Matthieu.Moy@imag.fr> writes:
Show 9 quoted lines
> +BEGIN { $| = 1 };
> +if (!eof(STDIN)) {
> + # Wait for Git to terminate. If we don't, git fetch
> + # (transport-helper.c's sendline function) will try to write
> + # to our stdin, which will be closed, and git fetch will be
> + # killed. That's probably a bug in transport-helper.c, but in
> + # the meantime ...
> + sleep .1;
> +};I was expecting this part to be more controversial, so I'm just repeating it to draw more attention ;-).
I just found a "cleaner" way to terminate, but I still don't find it really satisfactory:
# Inform Git that we're done, otherwise Git won't close it's stdin, # and the next loop will be infinite. close(STDOUT); # Flush stdin before we terminate. If we don't, git fetch # (transport-helper.c's sendline function) will try to write to our # stdin, which may be closed, and git fetch will be killed. That's # probably a bug in transport-helper.c, but in the meantime ... while (<STDIN>) {};
This seems reliable (just did 100+ imports without crash).
If I comment-out the "close(STDOUT)", then the while loop is indeed infinite. If I comment-out the "while (<STDIN>) {};", then the import unreliably fails (for example, I just did 10 clones of a 1-page wiki, and got one failure). No error message, just a non-zero exit status, and in the case of "clone", the newly created repository is deleted before the command terminates.
With debug activated in transport-helper.c, the last messages are just:
Debug: Disconnecting. Debug: Remote helper: ->
and gdb says:
Program received signal SIGPIPE, Broken pipe. 0xb7fe2424 in __kernel_vsyscall () (gdb) bt #0 0xb7fe2424 in __kernel_vsyscall () #1 0xb7e66ff3 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:82 #2 0x0811dc08 in xwrite (fd=8, buf=0x81bd840, len=1) at wrapper.c:137 #3 0x0811dc67 in write_in_full (fd=8, buf=0x81bd840, count=1) at wrapper.c:169 #4 0x08115035 in sendline (helper=0x81a2d00, buffer=0xbfffe674) at transport-helper.c:41 #5 0x081158f3 in disconnect_helper (transport=0x81a2cc0) at transport-helper.c:231 #6 release_helper (transport=0x81a2cc0) at transport-helper.c:324 #7 0x08111f1d in transport_disconnect (transport=0x81a2cc0) at transport.c:1144 #8 0x08061711 in cmd_clone (argc=3, argv=0xbfffeb58, prefix=0x0) at builtin/clone.c:739 #9 0x0804ba27 in run_builtin (argc=<value optimized out>, argv=<value optimized out>) at git.c:308 #10 handle_internal_command (argc=<value optimized out>, argv=<value optimized out>) at git.c:466 #11 0x0804bc33 in run_argv (argc=3, argv=0xbfffeb58) at git.c:512 #12 main (argc=3, argv=0xbfffeb58) at git.c:585
Any idea how to fix this?
-- Matthieu Moy http://www-verimag.imag.fr/~moy/