Skip to content

Commit 2fff781

Browse files
mhaggergitster
authored andcommitted
refs: wrap the packed refs cache in a level of indirection
As we know, we can solve any problem in this manner. In this case, the problem is to avoid freeing a packed refs cache while somebody is using it. So add a level of indirection as a prelude to reference-counting the packed refs cache. Signed-off-by: Michael Haggerty <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 267f9a8 commit 2fff781

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

refs.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -806,14 +806,18 @@ static int is_refname_available(const char *refname, const char *oldrefname,
806806
return 1;
807807
}
808808

809+
struct packed_ref_cache {
810+
struct ref_entry *root;
811+
};
812+
809813
/*
810814
* Future: need to be in "struct repository"
811815
* when doing a full libification.
812816
*/
813817
static struct ref_cache {
814818
struct ref_cache *next;
815819
struct ref_entry *loose;
816-
struct ref_entry *packed;
820+
struct packed_ref_cache *packed;
817821
/*
818822
* The submodule name, or "" for the main repo. We allocate
819823
* length 1 rather than FLEX_ARRAY so that the main ref_cache
@@ -825,7 +829,8 @@ static struct ref_cache {
825829
static void clear_packed_ref_cache(struct ref_cache *refs)
826830
{
827831
if (refs->packed) {
828-
free_ref_entry(refs->packed);
832+
free_ref_entry(refs->packed->root);
833+
free(refs->packed);
829834
refs->packed = NULL;
830835
}
831836
}
@@ -996,24 +1001,39 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
9961001
}
9971002
}
9981003

999-
static struct ref_dir *get_packed_refs(struct ref_cache *refs)
1004+
/*
1005+
* Get the packed_ref_cache for the specified ref_cache, creating it
1006+
* if necessary.
1007+
*/
1008+
static struct packed_ref_cache *get_packed_ref_cache(struct ref_cache *refs)
10001009
{
10011010
if (!refs->packed) {
10021011
const char *packed_refs_file;
10031012
FILE *f;
10041013

1005-
refs->packed = create_dir_entry(refs, "", 0, 0);
1014+
refs->packed = xcalloc(1, sizeof(*refs->packed));
1015+
refs->packed->root = create_dir_entry(refs, "", 0, 0);
10061016
if (*refs->name)
10071017
packed_refs_file = git_path_submodule(refs->name, "packed-refs");
10081018
else
10091019
packed_refs_file = git_path("packed-refs");
10101020
f = fopen(packed_refs_file, "r");
10111021
if (f) {
1012-
read_packed_refs(f, get_ref_dir(refs->packed));
1022+
read_packed_refs(f, get_ref_dir(refs->packed->root));
10131023
fclose(f);
10141024
}
10151025
}
1016-
return get_ref_dir(refs->packed);
1026+
return refs->packed;
1027+
}
1028+
1029+
static struct ref_dir *get_packed_ref_dir(struct packed_ref_cache *packed_ref_cache)
1030+
{
1031+
return get_ref_dir(packed_ref_cache->root);
1032+
}
1033+
1034+
static struct ref_dir *get_packed_refs(struct ref_cache *refs)
1035+
{
1036+
return get_packed_ref_dir(get_packed_ref_cache(refs));
10171037
}
10181038

10191039
void add_packed_ref(const char *refname, const unsigned char *sha1)

0 commit comments

Comments
 (0)