On Mon, Apr 13, 2020 at 02:05:00PM +0200, Son Luong Ngoc wrote: > I am trying to write a simple git trace2 event collector and I notice > that when git doing git pull with trace events being sent to a unix > stream socket, the entire operation halted. > > Reproduce as follow: > ``` > cd git/git > git config trace2.eventTarget af_unix:stream:/tmp/git_trace.sock > git config trace2.eventBrief false > (rm /tmp/git_trace.sock | ) && nc -lkU /tmp/git_trace.sock > > # In a different terminal > git pull # Pull stuck and never complete > ``` I think the issue is the use of netcat as the server side. Your git-pull involves multiple simultaneously-running Git processes. But "nc -k" will only accept() a new client once the old one has disconnected. So we'd deadlock any time we have this situation: - process A opens a stream to the socket, and keeps it open - process A spawns process B and waits for it to finish - process B tries to open a stream to the socket, which will block waiting for netcat to accept() Now A cannot make forward progress until B finishes, but B will not make forward progress until A closes the socket. I was able to reproduce the issue locally, and process "A" was git-pull and process "B" was git-merge. Switching to using datagrams ("nc -u" and "af_unix:dgram") makes the problem go away, because the connections are able to interleave their packets. > This does not happen when you set eventBrief to true > ``` > git config trace2.eventBrief true > ``` I don't know why this would matter (and it didn't seem to in my tests). > Worth to note that if eventTarget is a file instead of a socket, > everything works fine. That makes sense, since their file writes can be interleaved. -Peff