{"thread":{"id":"24654","subject":"[PATCH] smart-http: Don't deadlock on server failure","startedAt":"2010-08-06T21:19:44Z","lastAt":"2010-08-06T21:19:44Z","messageCount":1,"participants":["Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"147350","messageId":"1281129584-18781-1-git-send-email-spearce@spearce.org","threadId":"24654","inReplyTo":null,"subject":"[PATCH] smart-http: Don't deadlock on server failure","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-08-06T21:19:44Z","receivedAt":"2010-08-06T21:19:44Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"If the remote HTTP server fails (e.g. returns 404 or 500) when we\nposted the RPC to it, we won't have sent anything to the background\nGit process that is supposed to handle the stream.  Because we\ndidn't send anything, its waiting for input from remote-curl, and\nremote-curl cannot read its response payload because doing so would\nlead to a deadlock.\n\nSend the background task EOF on its input before we try to read\nits response back, that way it will break out of its read loop\nand terminate.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n\n This was found in Git 1.6.6.1, and exists since we added smart HTTP\n in 1.6.6.  Should apply at least to 'maint', if not older... :-)\n\n remote-curl.c |    5 +++--\n 1 files changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 8f169dd..c9d8f60 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -491,11 +491,12 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)\n \t\trpc->len = n;\n \t\terr |= post_rpc(rpc);\n \t}\n-\tstrbuf_read(&rpc->result, client.out, 0);\n \n \tclose(client.in);\n-\tclose(client.out);\n \tclient.in = -1;\n+\tstrbuf_read(&rpc->result, client.out, 0);\n+\n+\tclose(client.out);\n \tclient.out = -1;\n \n \terr |= finish_command(&client);\n-- \n1.7.2.1.52.g7f7860\n"}]}