Skip to content

Commit baa7b67

Browse files
Nick HengeveldJunio C Hamano
authored andcommitted
HTTP slot reuse fixes
Incorporate into http-push a fix related to accessing slot results after the slot was reused, and fix a case in run_active_slot where a finished slot wasn't detected if the slot was reused. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5241bfe commit baa7b67

File tree

3 files changed

+49
-20
lines changed

3 files changed

+49
-20
lines changed

http-push.c

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ static void start_move(struct transfer_request *request)
302302
static int refresh_lock(struct remote_lock *check_lock)
303303
{
304304
struct active_request_slot *slot;
305+
struct slot_results results;
305306
char *if_header;
306307
char timeout_header[25];
307308
struct curl_slist *dav_headers = NULL;
@@ -329,6 +330,7 @@ static int refresh_lock(struct remote_lock *check_lock)
329330
dav_headers = curl_slist_append(dav_headers, timeout_header);
330331

331332
slot = get_active_slot();
333+
slot->results = &results;
332334
curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
333335
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
334336
curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
@@ -337,8 +339,8 @@ static int refresh_lock(struct remote_lock *check_lock)
337339

338340
if (start_active_slot(slot)) {
339341
run_active_slot(slot);
340-
if (slot->curl_result != CURLE_OK) {
341-
fprintf(stderr, "Got HTTP error %ld\n", slot->http_code);
342+
if (results.curl_result != CURLE_OK) {
343+
fprintf(stderr, "Got HTTP error %ld\n", results.http_code);
342344
lock->active = 0;
343345
} else {
344346
lock->active = 1;
@@ -509,16 +511,18 @@ static int fetch_index(unsigned char *sha1)
509511

510512
FILE *indexfile;
511513
struct active_request_slot *slot;
514+
struct slot_results results;
512515

513516
/* Don't use the index if the pack isn't there */
514517
url = xmalloc(strlen(remote->url) + 65);
515518
sprintf(url, "%s/objects/pack/pack-%s.pack", remote->url, hex);
516519
slot = get_active_slot();
520+
slot->results = &results;
517521
curl_easy_setopt(slot->curl, CURLOPT_URL, url);
518522
curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
519523
if (start_active_slot(slot)) {
520524
run_active_slot(slot);
521-
if (slot->curl_result != CURLE_OK) {
525+
if (results.curl_result != CURLE_OK) {
522526
free(url);
523527
return error("Unable to verify pack %s is available",
524528
hex);
@@ -543,6 +547,7 @@ static int fetch_index(unsigned char *sha1)
543547
filename);
544548

545549
slot = get_active_slot();
550+
slot->results = &results;
546551
curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
547552
curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
548553
curl_easy_setopt(slot->curl, CURLOPT_FILE, indexfile);
@@ -566,7 +571,7 @@ static int fetch_index(unsigned char *sha1)
566571

567572
if (start_active_slot(slot)) {
568573
run_active_slot(slot);
569-
if (slot->curl_result != CURLE_OK) {
574+
if (results.curl_result != CURLE_OK) {
570575
free(url);
571576
fclose(indexfile);
572577
return error("Unable to get pack index %s\n%s", url,
@@ -606,6 +611,7 @@ static int fetch_indices(void)
606611
int i = 0;
607612

608613
struct active_request_slot *slot;
614+
struct slot_results results;
609615

610616
data = xmalloc(4096);
611617
memset(data, 0, 4096);
@@ -620,16 +626,17 @@ static int fetch_indices(void)
620626
sprintf(url, "%s/objects/info/packs", remote->url);
621627

622628
slot = get_active_slot();
629+
slot->results = &results;
623630
curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);
624631
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
625632
curl_easy_setopt(slot->curl, CURLOPT_URL, url);
626633
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);
627634
if (start_active_slot(slot)) {
628635
run_active_slot(slot);
629-
if (slot->curl_result != CURLE_OK) {
636+
if (results.curl_result != CURLE_OK) {
630637
free(buffer.buffer);
631638
free(url);
632-
if (slot->http_code == 404)
639+
if (results.http_code == 404)
633640
return 0;
634641
else
635642
return error("%s", curl_errorstr);
@@ -716,20 +723,22 @@ int fetch_ref(char *ref, unsigned char *sha1)
716723
struct buffer buffer;
717724
char *base = remote->url;
718725
struct active_request_slot *slot;
726+
struct slot_results results;
719727
buffer.size = 41;
720728
buffer.posn = 0;
721729
buffer.buffer = hex;
722730
hex[41] = '\0';
723-
731+
724732
url = quote_ref_url(base, ref);
725733
slot = get_active_slot();
734+
slot->results = &results;
726735
curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);
727736
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
728737
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);
729738
curl_easy_setopt(slot->curl, CURLOPT_URL, url);
730739
if (start_active_slot(slot)) {
731740
run_active_slot(slot);
732-
if (slot->curl_result != CURLE_OK)
741+
if (results.curl_result != CURLE_OK)
733742
return error("Couldn't get %s for %s\n%s",
734743
url, ref, curl_errorstr);
735744
} else {
@@ -913,6 +922,7 @@ xml_cdata(void *userData, const XML_Char *s, int len)
913922
static struct remote_lock *lock_remote(char *path, long timeout)
914923
{
915924
struct active_request_slot *slot;
925+
struct slot_results results;
916926
struct buffer out_buffer;
917927
struct buffer in_buffer;
918928
char *out_data;
@@ -946,14 +956,15 @@ static struct remote_lock *lock_remote(char *path, long timeout)
946956
while (ep) {
947957
*ep = 0;
948958
slot = get_active_slot();
959+
slot->results = &results;
949960
curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
950961
curl_easy_setopt(slot->curl, CURLOPT_URL, url);
951962
curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MKCOL);
952963
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
953964
if (start_active_slot(slot)) {
954965
run_active_slot(slot);
955-
if (slot->curl_result != CURLE_OK &&
956-
slot->http_code != 405) {
966+
if (results.curl_result != CURLE_OK &&
967+
results.http_code != 405) {
957968
fprintf(stderr,
958969
"Unable to create branch path %s\n",
959970
url);
@@ -985,6 +996,7 @@ static struct remote_lock *lock_remote(char *path, long timeout)
985996
dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
986997

987998
slot = get_active_slot();
999+
slot->results = &results;
9881000
curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
9891001
curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);
9901002
curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
@@ -1003,7 +1015,7 @@ static struct remote_lock *lock_remote(char *path, long timeout)
10031015

10041016
if (start_active_slot(slot)) {
10051017
run_active_slot(slot);
1006-
if (slot->curl_result == CURLE_OK) {
1018+
if (results.curl_result == CURLE_OK) {
10071019
ctx.name = xcalloc(10, 1);
10081020
ctx.len = 0;
10091021
ctx.cdata = NULL;
@@ -1053,6 +1065,7 @@ static struct remote_lock *lock_remote(char *path, long timeout)
10531065
static int unlock_remote(struct remote_lock *lock)
10541066
{
10551067
struct active_request_slot *slot;
1068+
struct slot_results results;
10561069
char *lock_token_header;
10571070
struct curl_slist *dav_headers = NULL;
10581071
int rc = 0;
@@ -1063,18 +1076,19 @@ static int unlock_remote(struct remote_lock *lock)
10631076
dav_headers = curl_slist_append(dav_headers, lock_token_header);
10641077

10651078
slot = get_active_slot();
1079+
slot->results = &results;
10661080
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
10671081
curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
10681082
curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_UNLOCK);
10691083
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
10701084

10711085
if (start_active_slot(slot)) {
10721086
run_active_slot(slot);
1073-
if (slot->curl_result == CURLE_OK)
1087+
if (results.curl_result == CURLE_OK)
10741088
rc = 1;
10751089
else
10761090
fprintf(stderr, "Got HTTP error %ld\n",
1077-
slot->http_code);
1091+
results.http_code);
10781092
} else {
10791093
fprintf(stderr, "Unable to start request\n");
10801094
}
@@ -1091,6 +1105,7 @@ static void crawl_remote_refs(char *path)
10911105
{
10921106
char *url;
10931107
struct active_request_slot *slot;
1108+
struct slot_results results;
10941109
struct buffer in_buffer;
10951110
struct buffer out_buffer;
10961111
char *in_data;
@@ -1125,6 +1140,7 @@ static void crawl_remote_refs(char *path)
11251140
dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
11261141

11271142
slot = get_active_slot();
1143+
slot->results = &results;
11281144
curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
11291145
curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);
11301146
curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
@@ -1137,7 +1153,7 @@ static void crawl_remote_refs(char *path)
11371153

11381154
if (start_active_slot(slot)) {
11391155
run_active_slot(slot);
1140-
if (slot->curl_result == CURLE_OK) {
1156+
if (results.curl_result == CURLE_OK) {
11411157
ctx.name = xcalloc(10, 1);
11421158
ctx.len = 0;
11431159
ctx.cdata = NULL;
@@ -1171,6 +1187,7 @@ static void get_remote_object_list(unsigned char parent)
11711187
{
11721188
char *url;
11731189
struct active_request_slot *slot;
1190+
struct slot_results results;
11741191
struct buffer in_buffer;
11751192
struct buffer out_buffer;
11761193
char *in_data;
@@ -1203,6 +1220,7 @@ static void get_remote_object_list(unsigned char parent)
12031220
dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
12041221

12051222
slot = get_active_slot();
1223+
slot->results = &results;
12061224
curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
12071225
curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);
12081226
curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
@@ -1215,7 +1233,7 @@ static void get_remote_object_list(unsigned char parent)
12151233

12161234
if (start_active_slot(slot)) {
12171235
run_active_slot(slot);
1218-
if (slot->curl_result == CURLE_OK) {
1236+
if (results.curl_result == CURLE_OK) {
12191237
remote_dir_exists[parent] = 1;
12201238
ctx.name = xcalloc(10, 1);
12211239
ctx.len = 0;
@@ -1250,6 +1268,7 @@ static void get_remote_object_list(unsigned char parent)
12501268
static int locking_available(void)
12511269
{
12521270
struct active_request_slot *slot;
1271+
struct slot_results results;
12531272
struct buffer in_buffer;
12541273
struct buffer out_buffer;
12551274
char *in_data;
@@ -1276,8 +1295,9 @@ static int locking_available(void)
12761295

12771296
dav_headers = curl_slist_append(dav_headers, "Depth: 0");
12781297
dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
1279-
1298+
12801299
slot = get_active_slot();
1300+
slot->results = &results;
12811301
curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
12821302
curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);
12831303
curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
@@ -1290,7 +1310,7 @@ static int locking_available(void)
12901310

12911311
if (start_active_slot(slot)) {
12921312
run_active_slot(slot);
1293-
if (slot->curl_result == CURLE_OK) {
1313+
if (results.curl_result == CURLE_OK) {
12941314
ctx.name = xcalloc(10, 1);
12951315
ctx.len = 0;
12961316
ctx.cdata = NULL;
@@ -1416,6 +1436,7 @@ static void get_delta(struct rev_info *revs, struct remote_lock *lock)
14161436
static int update_remote(unsigned char *sha1, struct remote_lock *lock)
14171437
{
14181438
struct active_request_slot *slot;
1439+
struct slot_results results;
14191440
char *out_data;
14201441
char *if_header;
14211442
struct buffer out_buffer;
@@ -1437,6 +1458,7 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock)
14371458
out_buffer.buffer = out_data;
14381459

14391460
slot = get_active_slot();
1461+
slot->results = &results;
14401462
curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
14411463
curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);
14421464
curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
@@ -1451,10 +1473,10 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock)
14511473
run_active_slot(slot);
14521474
free(out_data);
14531475
free(if_header);
1454-
if (slot->curl_result != CURLE_OK) {
1476+
if (results.curl_result != CURLE_OK) {
14551477
fprintf(stderr,
14561478
"PUT error: curl result=%d, HTTP code=%ld\n",
1457-
slot->curl_result, slot->http_code);
1479+
results.curl_result, results.http_code);
14581480
/* We should attempt recovery? */
14591481
return 0;
14601482
}

http.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ struct active_request_slot *get_active_slot(void)
339339
slot->in_use = 1;
340340
slot->local = NULL;
341341
slot->results = NULL;
342+
slot->finished = NULL;
342343
slot->callback_data = NULL;
343344
slot->callback_func = NULL;
344345
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, pragma_header);
@@ -389,8 +390,10 @@ void run_active_slot(struct active_request_slot *slot)
389390
fd_set excfds;
390391
int max_fd;
391392
struct timeval select_timeout;
393+
int finished = 0;
392394

393-
while (slot->in_use) {
395+
slot->finished = &finished;
396+
while (!finished) {
394397
data_received = 0;
395398
step_active_slots();
396399

@@ -442,6 +445,9 @@ static void finish_active_slot(struct active_request_slot *slot)
442445
closedown_active_slot(slot);
443446
curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code);
444447

448+
if (slot->finished != NULL)
449+
(*slot->finished) = 1;
450+
445451
/* Store slot results so they can be read after the slot is reused */
446452
if (slot->results != NULL) {
447453
slot->results->curl_result = slot->curl_result;

http.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ struct active_request_slot
3535
int in_use;
3636
CURLcode curl_result;
3737
long http_code;
38+
int *finished;
3839
struct slot_results *results;
3940
void *callback_data;
4041
void (*callback_func)(void *data);

0 commit comments

Comments
 (0)