Skip to content

Commit d30fe89

Browse files
jonathantanmygitster
authored andcommitted
fetch-pack: make negotiation-related vars local
Reduce the number of global variables by making the priority queue and the count of non-common commits in it local, passing them as a struct to various functions where necessary. This also helps in the case that fetch_pack() is invoked twice in the same process (when tag following is required when using a transport that does not support tag following), in that different priority queues will now be used in each invocation, instead of reusing the possibly non-empty one. Signed-off-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent af1c90d commit d30fe89

File tree

1 file changed

+69
-47
lines changed

1 file changed

+69
-47
lines changed

fetch-pack.c

Lines changed: 69 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,12 @@ static int marked;
5050
*/
5151
#define MAX_IN_VAIN 256
5252

53-
static struct prio_queue rev_list = { compare_commits_by_commit_date };
54-
static int non_common_revs, multi_ack, use_sideband;
53+
struct negotiation_state {
54+
struct prio_queue rev_list;
55+
int non_common_revs;
56+
};
57+
58+
static int multi_ack, use_sideband;
5559
/* Allow specifying sha1 if it is a ref tip. */
5660
#define ALLOW_TIP_SHA1 01
5761
/* Allow request of a sha1 if it is reachable from a ref (possibly hidden ref). */
@@ -93,7 +97,9 @@ static void cache_one_alternate(const char *refname,
9397
cache->items[cache->nr++] = obj;
9498
}
9599

96-
static void for_each_cached_alternate(void (*cb)(struct object *))
100+
static void for_each_cached_alternate(struct negotiation_state *ns,
101+
void (*cb)(struct negotiation_state *,
102+
struct object *))
97103
{
98104
static int initialized;
99105
static struct alternate_object_cache cache;
@@ -105,38 +111,41 @@ static void for_each_cached_alternate(void (*cb)(struct object *))
105111
}
106112

107113
for (i = 0; i < cache.nr; i++)
108-
cb(cache.items[i]);
114+
cb(ns, cache.items[i]);
109115
}
110116

111-
static void rev_list_push(struct commit *commit, int mark)
117+
static void rev_list_push(struct negotiation_state *ns,
118+
struct commit *commit, int mark)
112119
{
113120
if (!(commit->object.flags & mark)) {
114121
commit->object.flags |= mark;
115122

116123
if (parse_commit(commit))
117124
return;
118125

119-
prio_queue_put(&rev_list, commit);
126+
prio_queue_put(&ns->rev_list, commit);
120127

121128
if (!(commit->object.flags & COMMON))
122-
non_common_revs++;
129+
ns->non_common_revs++;
123130
}
124131
}
125132

126-
static int rev_list_insert_ref(const char *refname, const struct object_id *oid)
133+
static int rev_list_insert_ref(struct negotiation_state *ns,
134+
const char *refname,
135+
const struct object_id *oid)
127136
{
128137
struct object *o = deref_tag(parse_object(oid), refname, 0);
129138

130139
if (o && o->type == OBJ_COMMIT)
131-
rev_list_push((struct commit *)o, SEEN);
140+
rev_list_push(ns, (struct commit *)o, SEEN);
132141

133142
return 0;
134143
}
135144

136145
static int rev_list_insert_ref_oid(const char *refname, const struct object_id *oid,
137146
int flag, void *cb_data)
138147
{
139-
return rev_list_insert_ref(refname, oid);
148+
return rev_list_insert_ref(cb_data, refname, oid);
140149
}
141150

142151
static int clear_marks(const char *refname, const struct object_id *oid,
@@ -156,7 +165,7 @@ static int clear_marks(const char *refname, const struct object_id *oid,
156165
when only the server does not yet know that they are common).
157166
*/
158167

159-
static void mark_common(struct commit *commit,
168+
static void mark_common(struct negotiation_state *ns, struct commit *commit,
160169
int ancestors_only, int dont_parse)
161170
{
162171
if (commit != NULL && !(commit->object.flags & COMMON)) {
@@ -166,20 +175,21 @@ static void mark_common(struct commit *commit,
166175
o->flags |= COMMON;
167176

168177
if (!(o->flags & SEEN))
169-
rev_list_push(commit, SEEN);
178+
rev_list_push(ns, commit, SEEN);
170179
else {
171180
struct commit_list *parents;
172181

173182
if (!ancestors_only && !(o->flags & POPPED))
174-
non_common_revs--;
183+
ns->non_common_revs--;
175184
if (!o->parsed && !dont_parse)
176185
if (parse_commit(commit))
177186
return;
178187

179188
for (parents = commit->parents;
180189
parents;
181190
parents = parents->next)
182-
mark_common(parents->item, 0, dont_parse);
191+
mark_common(ns, parents->item, 0,
192+
dont_parse);
183193
}
184194
}
185195
}
@@ -188,24 +198,24 @@ static void mark_common(struct commit *commit,
188198
Get the next rev to send, ignoring the common.
189199
*/
190200

191-
static const struct object_id *get_rev(void)
201+
static const struct object_id *get_rev(struct negotiation_state *ns)
192202
{
193203
struct commit *commit = NULL;
194204

195205
while (commit == NULL) {
196206
unsigned int mark;
197207
struct commit_list *parents;
198208

199-
if (rev_list.nr == 0 || non_common_revs == 0)
209+
if (ns->rev_list.nr == 0 || ns->non_common_revs == 0)
200210
return NULL;
201211

202-
commit = prio_queue_get(&rev_list);
212+
commit = prio_queue_get(&ns->rev_list);
203213
parse_commit(commit);
204214
parents = commit->parents;
205215

206216
commit->object.flags |= POPPED;
207217
if (!(commit->object.flags & COMMON))
208-
non_common_revs--;
218+
ns->non_common_revs--;
209219

210220
if (commit->object.flags & COMMON) {
211221
/* do not send "have", and ignore ancestors */
@@ -220,9 +230,9 @@ static const struct object_id *get_rev(void)
220230

221231
while (parents) {
222232
if (!(parents->item->object.flags & SEEN))
223-
rev_list_push(parents->item, mark);
233+
rev_list_push(ns, parents->item, mark);
224234
if (mark & COMMON)
225-
mark_common(parents->item, 1, 0);
235+
mark_common(ns, parents->item, 1, 0);
226236
parents = parents->next;
227237
}
228238
}
@@ -296,9 +306,10 @@ static void send_request(struct fetch_pack_args *args,
296306
write_or_die(fd, buf->buf, buf->len);
297307
}
298308

299-
static void insert_one_alternate_object(struct object *obj)
309+
static void insert_one_alternate_object(struct negotiation_state *ns,
310+
struct object *obj)
300311
{
301-
rev_list_insert_ref(NULL, &obj->oid);
312+
rev_list_insert_ref(ns, NULL, &obj->oid);
302313
}
303314

304315
#define INITIAL_FLUSH 16
@@ -321,7 +332,8 @@ static int next_flush(int stateless_rpc, int count)
321332
return count;
322333
}
323334

324-
static int find_common(struct fetch_pack_args *args,
335+
static int find_common(struct negotiation_state *ns,
336+
struct fetch_pack_args *args,
325337
int fd[2], struct object_id *result_oid,
326338
struct ref *refs)
327339
{
@@ -337,8 +349,8 @@ static int find_common(struct fetch_pack_args *args,
337349
if (args->stateless_rpc && multi_ack == 1)
338350
die(_("--stateless-rpc requires multi_ack_detailed"));
339351

340-
for_each_ref(rev_list_insert_ref_oid, NULL);
341-
for_each_cached_alternate(insert_one_alternate_object);
352+
for_each_ref(rev_list_insert_ref_oid, ns);
353+
for_each_cached_alternate(ns, insert_one_alternate_object);
342354

343355
fetching = 0;
344356
for ( ; refs ; refs = refs->next) {
@@ -456,7 +468,7 @@ static int find_common(struct fetch_pack_args *args,
456468
retval = -1;
457469
if (args->no_dependents)
458470
goto done;
459-
while ((oid = get_rev())) {
471+
while ((oid = get_rev(ns))) {
460472
packet_buf_write(&req_buf, "have %s\n", oid_to_hex(oid));
461473
print_verbose(args, "have %s", oid_to_hex(oid));
462474
in_vain++;
@@ -514,7 +526,7 @@ static int find_common(struct fetch_pack_args *args,
514526
} else if (!args->stateless_rpc
515527
|| ack != ACK_common)
516528
in_vain = 0;
517-
mark_common(commit, 0, 1);
529+
mark_common(ns, commit, 0, 1);
518530
retval = 0;
519531
got_continue = 1;
520532
if (ack == ACK_ready)
@@ -704,7 +716,8 @@ static void filter_refs(struct fetch_pack_args *args,
704716
*refs = newlist;
705717
}
706718

707-
static void mark_alternate_complete(struct object *obj)
719+
static void mark_alternate_complete(struct negotiation_state *unused,
720+
struct object *obj)
708721
{
709722
mark_complete(&obj->oid);
710723
}
@@ -741,7 +754,8 @@ static int add_loose_objects_to_set(const struct object_id *oid,
741754
* earliest commit time of the objects in refs that are commits and that we know
742755
* the commit time of.
743756
*/
744-
static void mark_complete_and_common_ref(struct fetch_pack_args *args,
757+
static void mark_complete_and_common_ref(struct negotiation_state *ns,
758+
struct fetch_pack_args *args,
745759
struct ref **refs)
746760
{
747761
struct ref *ref;
@@ -792,7 +806,7 @@ static void mark_complete_and_common_ref(struct fetch_pack_args *args,
792806
if (!args->no_dependents) {
793807
if (!args->deepen) {
794808
for_each_ref(mark_complete_oid, NULL);
795-
for_each_cached_alternate(mark_alternate_complete);
809+
for_each_cached_alternate(NULL, mark_alternate_complete);
796810
commit_list_sort_by_date(&complete);
797811
if (cutoff)
798812
mark_recent_complete_commits(args, cutoff);
@@ -810,9 +824,10 @@ static void mark_complete_and_common_ref(struct fetch_pack_args *args,
810824
continue;
811825

812826
if (!(o->flags & SEEN)) {
813-
rev_list_push((struct commit *)o, COMMON_REF | SEEN);
827+
rev_list_push(ns, (struct commit *)o,
828+
COMMON_REF | SEEN);
814829

815-
mark_common((struct commit *)o, 1, 1);
830+
mark_common(ns, (struct commit *)o, 1, 1);
816831
}
817832
}
818833
}
@@ -995,6 +1010,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
9951010
struct object_id oid;
9961011
const char *agent_feature;
9971012
int agent_len;
1013+
struct negotiation_state ns = { { compare_commits_by_commit_date } };
9981014

9991015
sort_ref_list(&ref, ref_compare_name);
10001016
QSORT(sought, nr_sought, cmp_ref_by_name);
@@ -1070,13 +1086,13 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
10701086
if (marked)
10711087
for_each_ref(clear_marks, NULL);
10721088
marked = 1;
1073-
mark_complete_and_common_ref(args, &ref);
1089+
mark_complete_and_common_ref(&ns, args, &ref);
10741090
filter_refs(args, &ref, sought, nr_sought);
10751091
if (everything_local(args, &ref)) {
10761092
packet_flush(fd[1]);
10771093
goto all_done;
10781094
}
1079-
if (find_common(args, fd, &oid, ref) < 0)
1095+
if (find_common(&ns, args, fd, &oid, ref) < 0)
10801096
if (!args->keep_pack)
10811097
/* When cloning, it is not unusual to have
10821098
* no common commit.
@@ -1096,7 +1112,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
10961112
die(_("git fetch-pack: fetch failed."));
10971113

10981114
all_done:
1099-
clear_prio_queue(&rev_list);
1115+
clear_prio_queue(&ns.rev_list);
11001116
return ref;
11011117
}
11021118

@@ -1158,13 +1174,14 @@ static void add_common(struct strbuf *req_buf, struct oidset *common)
11581174
}
11591175
}
11601176

1161-
static int add_haves(struct strbuf *req_buf, int *haves_to_send, int *in_vain)
1177+
static int add_haves(struct negotiation_state *ns, struct strbuf *req_buf,
1178+
int *haves_to_send, int *in_vain)
11621179
{
11631180
int ret = 0;
11641181
int haves_added = 0;
11651182
const struct object_id *oid;
11661183

1167-
while ((oid = get_rev())) {
1184+
while ((oid = get_rev(ns))) {
11681185
packet_buf_write(req_buf, "have %s\n", oid_to_hex(oid));
11691186
if (++haves_added >= *haves_to_send)
11701187
break;
@@ -1183,7 +1200,8 @@ static int add_haves(struct strbuf *req_buf, int *haves_to_send, int *in_vain)
11831200
return ret;
11841201
}
11851202

1186-
static int send_fetch_request(int fd_out, const struct fetch_pack_args *args,
1203+
static int send_fetch_request(struct negotiation_state *ns, int fd_out,
1204+
const struct fetch_pack_args *args,
11871205
const struct ref *wants, struct oidset *common,
11881206
int *haves_to_send, int *in_vain)
11891207
{
@@ -1239,7 +1257,7 @@ static int send_fetch_request(int fd_out, const struct fetch_pack_args *args,
12391257
add_common(&req_buf, common);
12401258

12411259
/* Add initial haves */
1242-
ret = add_haves(&req_buf, haves_to_send, in_vain);
1260+
ret = add_haves(ns, &req_buf, haves_to_send, in_vain);
12431261
}
12441262

12451263
/* Send request */
@@ -1276,7 +1294,9 @@ static int process_section_header(struct packet_reader *reader,
12761294
return ret;
12771295
}
12781296

1279-
static int process_acks(struct packet_reader *reader, struct oidset *common)
1297+
static int process_acks(struct negotiation_state *ns,
1298+
struct packet_reader *reader,
1299+
struct oidset *common)
12801300
{
12811301
/* received */
12821302
int received_ready = 0;
@@ -1295,7 +1315,7 @@ static int process_acks(struct packet_reader *reader, struct oidset *common)
12951315
struct commit *commit;
12961316
oidset_insert(common, &oid);
12971317
commit = lookup_commit(&oid);
1298-
mark_common(commit, 0, 1);
1318+
mark_common(ns, commit, 0, 1);
12991319
}
13001320
continue;
13011321
}
@@ -1373,6 +1393,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
13731393
struct packet_reader reader;
13741394
int in_vain = 0;
13751395
int haves_to_send = INITIAL_FLUSH;
1396+
struct negotiation_state ns = { { compare_commits_by_commit_date } };
13761397
packet_reader_init(&reader, fd[0], NULL, 0,
13771398
PACKET_READ_CHOMP_NEWLINE);
13781399

@@ -1393,26 +1414,27 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
13931414
marked = 1;
13941415

13951416
/* Filter 'ref' by 'sought' and those that aren't local */
1396-
mark_complete_and_common_ref(args, &ref);
1417+
mark_complete_and_common_ref(&ns, args, &ref);
13971418
filter_refs(args, &ref, sought, nr_sought);
13981419
if (everything_local(args, &ref))
13991420
state = FETCH_DONE;
14001421
else
14011422
state = FETCH_SEND_REQUEST;
14021423

1403-
for_each_ref(rev_list_insert_ref_oid, NULL);
1404-
for_each_cached_alternate(insert_one_alternate_object);
1424+
for_each_ref(rev_list_insert_ref_oid, &ns);
1425+
for_each_cached_alternate(&ns,
1426+
insert_one_alternate_object);
14051427
break;
14061428
case FETCH_SEND_REQUEST:
1407-
if (send_fetch_request(fd[1], args, ref, &common,
1429+
if (send_fetch_request(&ns, fd[1], args, ref, &common,
14081430
&haves_to_send, &in_vain))
14091431
state = FETCH_GET_PACK;
14101432
else
14111433
state = FETCH_PROCESS_ACKS;
14121434
break;
14131435
case FETCH_PROCESS_ACKS:
14141436
/* Process ACKs/NAKs */
1415-
switch (process_acks(&reader, &common)) {
1437+
switch (process_acks(&ns, &reader, &common)) {
14161438
case 2:
14171439
state = FETCH_GET_PACK;
14181440
break;
@@ -1441,7 +1463,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
14411463
}
14421464
}
14431465

1444-
clear_prio_queue(&rev_list);
1466+
clear_prio_queue(&ns.rev_list);
14451467
oidset_clear(&common);
14461468
return ref;
14471469
}

0 commit comments

Comments
 (0)