1. 27 May, 2011 3 commits
  2. 26 May, 2011 3 commits
  3. 18 May, 2011 1 commit
  4. 17 May, 2011 1 commit
  5. 16 May, 2011 4 commits
    • Jeff King's avatar
      send-pack: avoid deadlock on git:// push with failed pack-objects · a1a3fd1f
      Jeff King authored
      Commit 09c9957c fixes a deadlock in which pack-objects
      fails, the remote end is still waiting for pack data, and we
      are still waiting for the remote end to say something (see
      that commit for a much more in-depth explanation).
      
      We solved the problem there by making sure the output pipe
      is closed on error; thus the remote sees EOF, and proceeds
      to complain and close its end of the connection.
      
      However, in the special case of push over git://, we don't
      have a pipe, but rather a full-duplex socket, with another
      dup()-ed descriptor in place of the second half of the pipe.
      In this case, closing the second descriptor signals nothing
      to the remote end, and we still deadlock.
      
      This patch calls shutdown() explicitly to signal EOF to the
      other side.
      Signed-off-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
      a1a3fd1f
    • Jeff King's avatar
      connect: let callers know if connection is a socket · 7ffe853b
      Jeff King authored
      They might care because they want to do a half-duplex close.
      With pipes, that means simply closing the output descriptor;
      with a socket, you must actually call shutdown.
      
      Instead of exposing the magic no_fork child_process struct,
      let's encapsulate the test in a function.
      Signed-off-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
      7ffe853b
    • Jeff King's avatar
      connect: treat generic proxy processes like ssh processes · 5cbf8246
      Jeff King authored
      The git_connect function returns two ends of a pipe for
      talking with a remote, plus a struct child_process
      representing the other end of the pipe. If we have a direct
      socket connection, then this points to a special "no_fork"
      child process.
      
      The code path for doing git-over-pipes or git-over-ssh sets
      up this child process to point to the child git command or
      the ssh process. When we call finish_connect eventually, we
      check wait() on the command and report its return value.
      
      The code path for git://, on the other hand, always sets it
      to no_fork. In the case of a direct TCP connection, this
      makes sense; we have no child process. But in the case of a
      proxy command (configured by core.gitproxy), we do have a
      child process, but we throw away its pid, and therefore
      ignore its return code.
      
      Instead, let's keep that information in the proxy case, and
      respect its return code, which can help catch some errors
      (though depending on your proxy command, it will be errors
      reported by the proxy command itself, and not propagated
      from git commands. Still, it is probably better to propagate
      such errors than to ignore them).
      
      It also means that the child_process field can reliably be
      used to determine whether the returned descriptors are
      actually a full-duplex socket, which means we should be
      using shutdown() instead of a simple close.
      Signed-off-by: default avatarJeff King <[email protected]>
      Helped-by: default avatarJohannes Sixt <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
      5cbf8246
    • Junio C Hamano's avatar
      sideband_demux(): fix decl-after-stmt · 61432146
      Junio C Hamano authored
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
      61432146
  6. 05 May, 2011 2 commits
    • Junio C Hamano's avatar
      Merge branch 'js/maint-1.6.6-send-pack-stateless-rpc-deadlock-fix' into... · 80b5b698
      Junio C Hamano authored
      Merge branch 'js/maint-1.6.6-send-pack-stateless-rpc-deadlock-fix' into js/maint-send-pack-stateless-rpc-deadlock-fix
      
      * js/maint-1.6.6-send-pack-stateless-rpc-deadlock-fix:
        send-pack: unbreak push over stateless rpc
      80b5b698
    • Jeff King's avatar
      send-pack: unbreak push over stateless rpc · e07fd15b
      Jeff King authored
      Commit 09c9957c (send-pack: avoid deadlock when pack-object
      dies early, 2011-04-25) attempted to fix a hang in the
      stateless rpc case by closing a file descriptor early, but
      we still need that descriptor.
      
      Basically the deadlock can happen when pack-objects fails,
      and the descriptor to upstream is left open. We never send
      the pack, so the upstream is left waiting for us to say
      something, and we are left waiting for upstream to close the
      connection.
      
      In the non-rpc case, our descriptor points straight to the
      upstream. We hand it off to run-command, which takes
      ownership and closes the descriptor after pack-objects
      finishes (whether it succeeds or not).
      
      Commit 09c9957c tried to emulate that in the rpc case. That
      isn't right, though. We actually have a descriptor going
      back to the remote-helper, and we need to keep using it
      after pack-objects is finished. Closing it early completely
      breaks pushing via smart-http.
      
      We still need to do something on error to signal the
      remote-helper that we won't be sending any pack data
      (otherwise we get the deadlock).  In an ideal world, we
      would send a special packet back that says "Sorry, there was
      an error". But the remote-helper doesn't understand any such
      packet, so the best we can do is close the descriptor and
      let it report that we hung up unexpectedly.
      Signed-off-by: default avatarJeff King <[email protected]>
      Acked-by: default avatarJohannes Sixt <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
      e07fd15b
  7. 25 Apr, 2011 2 commits
    • Junio C Hamano's avatar
      Merge branch 'js/maint-1.6.6-send-pack-stateless-rpc-deadlock-fix' into... · 73776dc1
      Junio C Hamano authored
      Merge branch 'js/maint-1.6.6-send-pack-stateless-rpc-deadlock-fix' into js/maint-send-pack-stateless-rpc-deadlock-fix
      
      * js/maint-1.6.6-send-pack-stateless-rpc-deadlock-fix:
        send-pack: avoid deadlock when pack-object dies early
      
      Evil merge to adjust the way the use of pthreads in sideband-demultiplexor
      was decided (earlier it was "if we are not on Windows", now it is "if we
      are not using pthreads").
      73776dc1
    • Johannes Sixt's avatar
      send-pack: avoid deadlock when pack-object dies early · 09c9957c
      Johannes Sixt authored
      Send-pack deadlocks in two ways when pack-object dies early (for example,
      because there is some repo corruption).
      
      The first deadlock happens with the smart push protocol (--stateless-rpc).
      After the initial rev-exchange, the remote is waiting for the pack data
      to arrive, and the sideband demuxer at the local side continues trying to
      stream data from the remote repository until it gets EOF. Meanwhile,
      send-pack (in function pack_objects()) has noticed that pack-objects did
      not produce output and died. Back in send_pack(), it now tries to clean
      up the sideband demuxer using finish_async(). The demuxer, however, waits
      for the remote end to close down, the remote waits for pack data, and
      the reason that it still waits is that send-pack forgot to close the
      outgoing channel. Add the missing close() in pack_objects().
      
      The second deadlock happens in a similar constellation when the sideband
      demuxer runs in a forked process (rather than in a thread). Again, the
      remote end waits for pack data to arrive, the sideband demuxer waits for
      the remote to shut down, and send-pack (in the regular clean-up) waits for
      the demuxer to terminate. This time, the send-pack parent process closes
      the writable end of the outgoing channel (in start_command() that spawned
      pack-objects) so that after the death of the pack-objects process all
      writable ends should have been closed and the remote repo should see EOF.
      This does not happen, however, because when the sideband demuxer was forked
      earlier, it also inherited a writable end; it remains open and keeps the
      remote repo from seeing EOF. To break this deadlock, close the writable end
      in the demuxer.
      Analyzed-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJohannes Sixt <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
      09c9957c
  8. 19 Apr, 2011 2 commits
  9. 14 Apr, 2011 3 commits
  10. 13 Apr, 2011 2 commits
  11. 12 Apr, 2011 1 commit
  12. 06 Apr, 2011 4 commits
    • Jeff King's avatar
      upload-pack: start pack-objects before async rev-list · b9612197
      Jeff King authored
      In a pthread-enabled version of upload-pack, there's a race condition
      that can cause a deadlock on the fflush(NULL) we call from run-command.
      
      What happens is this:
      
        1. Upload-pack is informed we are doing a shallow clone.
      
        2. We call start_async() to spawn a thread that will generate rev-list
           results to feed to pack-objects. It gets a file descriptor to a
           pipe which will eventually hook to pack-objects.
      
        3. The rev-list thread uses fdopen to create a new output stream
           around the fd we gave it, called pack_pipe.
      
        4. The thread writes results to pack_pipe. Outside of our control,
           libc is doing locking on the stream. We keep writing until the OS
           pipe buffer is full, and then we block in write(), still holding
           the lock.
      
        5. The main thread now uses start_command to spawn pack-objects.
           Before forking, it calls fflush(NULL) to flush every stdio output
           buffer. It blocks trying to get the lock on pack_pipe.
      
      And we have a deadlock. The thread will block until somebody starts
      reading from the pipe. But nobody will read from the pipe until we
      finish flushing to the pipe.
      
      To fix this, we swap the start order: we start the
      pack-objects reader first, and then the rev-list writer
      after. Thus the problematic fflush(NULL) happens before we
      even open the new file descriptor (and even if it didn't,
      flushing should no longer block, as the reader at the end of
      the pipe is now active).
      Signed-off-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
      b9612197
    • Junio C Hamano's avatar
      Git 1.7.4.4 · 5fb41b88
      Junio C Hamano authored
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
      5fb41b88
    • Junio C Hamano's avatar
      Merge branch 'nm/maint-conflicted-submodule-entries' into maint · 0c41f33c
      Junio C Hamano authored
      * nm/maint-conflicted-submodule-entries:
        submodule: process conflicting submodules only once
      0c41f33c
    • Junio C Hamano's avatar
      Merge branch 'mg/rev-list-n-reverse-doc' into maint · df0a6aeb
      Junio C Hamano authored
      * mg/rev-list-n-reverse-doc:
        git-log.txt,rev-list-options.txt: put option blocks in proper order
        git-log.txt,rev-list-options.txt: -n/--max-count is commit limiting
      df0a6aeb
  13. 04 Apr, 2011 2 commits
  14. 03 Apr, 2011 10 commits