mirror of
https://github.com/git/git
synced 2024-08-27 19:49:21 +00:00
grep: allocate subrepos on heap
Currently, struct repository objects corresponding to submodules are allocated on the stack in grep_submodule(). This currently works because they will not be used once grep_submodule() exits, but a subsequent patch will require these structs to be accessible for longer (perhaps even in another thread). Allocate them on the heap and clear them only at the very end. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Reviewed-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
78ca584f1c
commit
dd45471a37
|
@ -65,6 +65,9 @@ static int todo_done;
|
||||||
/* Has all work items been added? */
|
/* Has all work items been added? */
|
||||||
static int all_work_added;
|
static int all_work_added;
|
||||||
|
|
||||||
|
static struct repository **repos_to_free;
|
||||||
|
static size_t repos_to_free_nr, repos_to_free_alloc;
|
||||||
|
|
||||||
/* This lock protects all the variables above. */
|
/* This lock protects all the variables above. */
|
||||||
static pthread_mutex_t grep_mutex;
|
static pthread_mutex_t grep_mutex;
|
||||||
|
|
||||||
|
@ -168,6 +171,19 @@ static void work_done(struct work_item *w)
|
||||||
grep_unlock();
|
grep_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void free_repos(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < repos_to_free_nr; i++) {
|
||||||
|
repo_clear(repos_to_free[i]);
|
||||||
|
free(repos_to_free[i]);
|
||||||
|
}
|
||||||
|
FREE_AND_NULL(repos_to_free);
|
||||||
|
repos_to_free_nr = 0;
|
||||||
|
repos_to_free_alloc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void *run(void *arg)
|
static void *run(void *arg)
|
||||||
{
|
{
|
||||||
int hit = 0;
|
int hit = 0;
|
||||||
|
@ -415,19 +431,24 @@ static int grep_submodule(struct grep_opt *opt,
|
||||||
const struct object_id *oid,
|
const struct object_id *oid,
|
||||||
const char *filename, const char *path, int cached)
|
const char *filename, const char *path, int cached)
|
||||||
{
|
{
|
||||||
struct repository subrepo;
|
struct repository *subrepo;
|
||||||
struct repository *superproject = opt->repo;
|
struct repository *superproject = opt->repo;
|
||||||
const struct submodule *sub;
|
const struct submodule *sub;
|
||||||
struct grep_opt subopt;
|
struct grep_opt subopt;
|
||||||
int hit;
|
int hit = 0;
|
||||||
|
|
||||||
sub = submodule_from_path(superproject, null_oid(), path);
|
sub = submodule_from_path(superproject, null_oid(), path);
|
||||||
|
|
||||||
if (!is_submodule_active(superproject, path))
|
if (!is_submodule_active(superproject, path))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (repo_submodule_init(&subrepo, superproject, sub))
|
subrepo = xmalloc(sizeof(*subrepo));
|
||||||
|
if (repo_submodule_init(subrepo, superproject, sub)) {
|
||||||
|
free(subrepo);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
ALLOC_GROW(repos_to_free, repos_to_free_nr + 1, repos_to_free_alloc);
|
||||||
|
repos_to_free[repos_to_free_nr++] = subrepo;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NEEDSWORK: repo_read_gitmodules() might call
|
* NEEDSWORK: repo_read_gitmodules() might call
|
||||||
|
@ -438,7 +459,7 @@ static int grep_submodule(struct grep_opt *opt,
|
||||||
* subrepo's odbs to the in-memory alternates list.
|
* subrepo's odbs to the in-memory alternates list.
|
||||||
*/
|
*/
|
||||||
obj_read_lock();
|
obj_read_lock();
|
||||||
repo_read_gitmodules(&subrepo, 0);
|
repo_read_gitmodules(subrepo, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NEEDSWORK: This adds the submodule's object directory to the list of
|
* NEEDSWORK: This adds the submodule's object directory to the list of
|
||||||
|
@ -450,11 +471,11 @@ static int grep_submodule(struct grep_opt *opt,
|
||||||
* store is no longer global and instead is a member of the repository
|
* store is no longer global and instead is a member of the repository
|
||||||
* object.
|
* object.
|
||||||
*/
|
*/
|
||||||
add_submodule_odb_by_path(subrepo.objects->odb->path);
|
add_submodule_odb_by_path(subrepo->objects->odb->path);
|
||||||
obj_read_unlock();
|
obj_read_unlock();
|
||||||
|
|
||||||
memcpy(&subopt, opt, sizeof(subopt));
|
memcpy(&subopt, opt, sizeof(subopt));
|
||||||
subopt.repo = &subrepo;
|
subopt.repo = subrepo;
|
||||||
|
|
||||||
if (oid) {
|
if (oid) {
|
||||||
enum object_type object_type;
|
enum object_type object_type;
|
||||||
|
@ -464,9 +485,9 @@ static int grep_submodule(struct grep_opt *opt,
|
||||||
struct strbuf base = STRBUF_INIT;
|
struct strbuf base = STRBUF_INIT;
|
||||||
|
|
||||||
obj_read_lock();
|
obj_read_lock();
|
||||||
object_type = oid_object_info(&subrepo, oid, NULL);
|
object_type = oid_object_info(subrepo, oid, NULL);
|
||||||
obj_read_unlock();
|
obj_read_unlock();
|
||||||
data = read_object_with_reference(&subrepo,
|
data = read_object_with_reference(subrepo,
|
||||||
oid, tree_type,
|
oid, tree_type,
|
||||||
&size, NULL);
|
&size, NULL);
|
||||||
if (!data)
|
if (!data)
|
||||||
|
@ -484,7 +505,6 @@ static int grep_submodule(struct grep_opt *opt,
|
||||||
hit = grep_cache(&subopt, pathspec, cached);
|
hit = grep_cache(&subopt, pathspec, cached);
|
||||||
}
|
}
|
||||||
|
|
||||||
repo_clear(&subrepo);
|
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1182,5 +1202,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
||||||
run_pager(&opt, prefix);
|
run_pager(&opt, prefix);
|
||||||
clear_pathspec(&pathspec);
|
clear_pathspec(&pathspec);
|
||||||
free_grep_patterns(&opt);
|
free_grep_patterns(&opt);
|
||||||
|
free_repos();
|
||||||
return !hit;
|
return !hit;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue