{"thread":{"id":"3257","subject":"[PATCH] http-fetch: Abort requests for objects which arrived in packs","startedAt":"2006-02-07T10:07:39Z","lastAt":"2006-02-07T10:07:39Z","messageCount":1,"participants":["Mark Wooding"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"15667","messageId":"20060207100739.22520.49089.stgit@metalzone.distorted.org.uk","threadId":"3257","inReplyTo":null,"subject":"[PATCH] http-fetch: Abort requests for objects which arrived in packs","fromName":"Mark Wooding","fromEmail":"mdw@distorted.org.uk","sentAt":"2006-02-07T10:07:39Z","receivedAt":"2006-02-07T10:07:39Z","isPatch":true,"sender":{"key":"mdw@distorted.org.uk","avatar":null},"body":"From: Mark Wooding <mdw@distorted.org.uk>\n\nIn fetch_object, there's a call to release an object request if the\nobject mysteriously arrived, say in a pack.  Unfortunately, the fetch\nattempt for this object might already be in progress, and we'll leak the\ndescriptor.  Instead, try to tidy away the request.\n\nSigned-off-by: Mark Wooding <mdw@distorted.org.uk>\n---\n\n http-fetch.c |   16 +++++++++++++++-\n http.c       |   18 +++++++++++++++++-\n http.h       |    1 +\n 3 files changed, 33 insertions(+), 2 deletions(-)\n\ndiff --git a/http-fetch.c b/http-fetch.c\nindex bddbd6b..ce3df5f 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -773,6 +773,20 @@ static int fetch_pack(struct alt_base *r\n \treturn 0;\n }\n \n+static void abort_object_request(struct object_request *obj_req)\n+{\n+\tif (obj_req->local >= 0) {\n+\t\tclose(obj_req->local);\n+\t\tobj_req->local = -1;\n+\t}\n+\tunlink(obj_req->tmpfile);\n+\tif (obj_req->slot) {\n+ \t\trelease_active_slot(obj_req->slot);\n+\t\tobj_req->slot = NULL;\n+\t}\n+\trelease_object_request(obj_req);\n+}\n+\n static int fetch_object(struct alt_base *repo, unsigned char *sha1)\n {\n \tchar *hex = sha1_to_hex(sha1);\n@@ -785,7 +799,7 @@ static int fetch_object(struct alt_base \n \t\treturn error(\"Couldn't find request for %s in the queue\", hex);\n \n \tif (has_sha1_file(obj_req->sha1)) {\n-\t\trelease_object_request(obj_req);\n+\t\tabort_object_request(obj_req);\n \t\treturn 0;\n \t}\n \ndiff --git a/http.c b/http.c\nindex 632c2c5..14a7669 100644\n--- a/http.c\n+++ b/http.c\n@@ -420,10 +420,26 @@ void run_active_slot(struct active_reque\n #endif\n }\n \n-static void finish_active_slot(struct active_request_slot *slot)\n+static void closedown_active_slot(struct active_request_slot *slot)\n {\n         active_requests--;\n         slot->in_use = 0;\n+}\n+\n+void release_active_slot(struct active_request_slot *slot)\n+{\n+\tclosedown_active_slot(slot);\n+\tif (slot->curl) {\n+\t\tcurl_multi_remove_handle(curlm, slot->curl);\n+\t\tcurl_easy_cleanup(slot->curl);\n+\t\tslot->curl = NULL;\n+\t}\n+\tfill_active_slots();\n+}\n+\n+static void finish_active_slot(struct active_request_slot *slot)\n+{\n+\tclosedown_active_slot(slot);\n         curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code);\n \n \t/* Store slot results so they can be read after the slot is reused */\ndiff --git a/http.h b/http.h\nindex d6dc9d8..36fa154 100644\n--- a/http.h\n+++ b/http.h\n@@ -61,6 +61,7 @@ extern struct active_request_slot *get_a\n extern int start_active_slot(struct active_request_slot *slot);\n extern void run_active_slot(struct active_request_slot *slot);\n extern void finish_all_active_slots(void);\n+extern void release_active_slot(struct active_request_slot *slot);\n \n #ifdef USE_CURL_MULTI\n extern void fill_active_slots(void);\n"}]}