summaryrefslogtreecommitdiff
path: root/graph.c
diff options
context:
space:
mode:
authorLibravatar Johannes Sixt <j6t@kdbg.org>2011-04-25 23:04:10 +0200
committerLibravatar Junio C Hamano <gitster@pobox.com>2011-04-25 15:13:24 -0700
commit09c9957cf77106ca6b49127d5df20080922c81a4 (patch)
tree2cfdb321d1dfdb96c97a37070f6e91fa0bdba67f /graph.c
parentreceive-pack: Wrap status reports inside side-band-64k (diff)
downloadtgif-09c9957cf77106ca6b49127d5df20080922c81a4.tar.xz
send-pack: avoid deadlock when pack-object dies early
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: Jeff King <peff@peff.net> Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'graph.c')
0 files changed, 0 insertions, 0 deletions