Commit 178aa39c by Russell Belfer

Be more thread aware with some index updates

The index isn't really thread safe for the most part, but we can
easily be more careful and avoid double frees and the like, which
are serious problems (as opposed to a lookup which might return
the incorrect value but if the index in being updated, that is
much harder to avoid).
parent 6bb7bff2
...@@ -261,6 +261,22 @@ static int reuc_icmp(const void *a, const void *b) ...@@ -261,6 +261,22 @@ static int reuc_icmp(const void *a, const void *b)
return strcasecmp(info_a->path, info_b->path); return strcasecmp(info_a->path, info_b->path);
} }
static void index_entry_reuc_free(git_index_reuc_entry *reuc)
{
if (!reuc)
return;
git__free(reuc->path);
git__free(reuc);
}
static void index_entry_free(git_index_entry *entry)
{
if (!entry)
return;
git__free(entry->path);
git__free(entry);
}
static unsigned int index_create_mode(unsigned int mode) static unsigned int index_create_mode(unsigned int mode)
{ {
if (S_ISLNK(mode)) if (S_ISLNK(mode))
...@@ -367,11 +383,8 @@ static void index_entries_free(git_vector *entries) ...@@ -367,11 +383,8 @@ static void index_entries_free(git_vector *entries)
{ {
size_t i; size_t i;
for (i = 0; i < entries->length; ++i) { for (i = 0; i < entries->length; ++i)
git_index_entry *e = git_vector_get(entries, i); index_entry_free(git__swap(entries->contents[i], NULL));
git__free(e->path);
git__free(e);
}
git_vector_clear(entries); git_vector_clear(entries);
} }
...@@ -670,15 +683,6 @@ static int index_entry_reuc_init(git_index_reuc_entry **reuc_out, ...@@ -670,15 +683,6 @@ static int index_entry_reuc_init(git_index_reuc_entry **reuc_out,
return 0; return 0;
} }
static void index_entry_reuc_free(git_index_reuc_entry *reuc)
{
if (!reuc)
return;
git__free(reuc->path);
git__free(reuc);
}
static git_index_entry *index_entry_dup(const git_index_entry *source_entry) static git_index_entry *index_entry_dup(const git_index_entry *source_entry)
{ {
git_index_entry *entry; git_index_entry *entry;
...@@ -697,14 +701,6 @@ static git_index_entry *index_entry_dup(const git_index_entry *source_entry) ...@@ -697,14 +701,6 @@ static git_index_entry *index_entry_dup(const git_index_entry *source_entry)
return entry; return entry;
} }
static void index_entry_free(git_index_entry *entry)
{
if (!entry)
return;
git__free(entry->path);
git__free(entry);
}
static int index_insert(git_index *index, git_index_entry *entry, int replace) static int index_insert(git_index *index, git_index_entry *entry, int replace)
{ {
size_t path_length, position; size_t path_length, position;
...@@ -1357,14 +1353,11 @@ int git_index_reuc_remove(git_index *index, size_t position) ...@@ -1357,14 +1353,11 @@ int git_index_reuc_remove(git_index *index, size_t position)
void git_index_reuc_clear(git_index *index) void git_index_reuc_clear(git_index *index)
{ {
size_t i; size_t i;
git_index_reuc_entry *reuc;
assert(index); assert(index);
git_vector_foreach(&index->reuc, i, reuc) { for (i = 0; i < index->reuc.length; ++i)
git__free(reuc->path); index_entry_reuc_free(git__swap(index->reuc.contents[i], NULL));
git__free(reuc);
}
git_vector_clear(&index->reuc); git_vector_clear(&index->reuc);
} }
...@@ -1958,8 +1951,9 @@ int git_index_entry_stage(const git_index_entry *entry) ...@@ -1958,8 +1951,9 @@ int git_index_entry_stage(const git_index_entry *entry)
} }
typedef struct read_tree_data { typedef struct read_tree_data {
git_index *index;
git_vector *old_entries; git_vector *old_entries;
git_vector *new_entries;
git_vector_cmp entries_search;
} read_tree_data; } read_tree_data;
static int read_tree_cb( static int read_tree_cb(
...@@ -1990,7 +1984,7 @@ static int read_tree_cb( ...@@ -1990,7 +1984,7 @@ static int read_tree_cb(
skey.stage = 0; skey.stage = 0;
if (!git_vector_bsearch2( if (!git_vector_bsearch2(
&pos, data->old_entries, data->index->entries_search, &skey) && &pos, data->old_entries, data->entries_search, &skey) &&
(old_entry = git_vector_get(data->old_entries, pos)) != NULL && (old_entry = git_vector_get(data->old_entries, pos)) != NULL &&
entry->mode == old_entry->mode && entry->mode == old_entry->mode &&
git_oid_equal(&entry->oid, &old_entry->oid)) git_oid_equal(&entry->oid, &old_entry->oid))
...@@ -2008,7 +2002,7 @@ static int read_tree_cb( ...@@ -2008,7 +2002,7 @@ static int read_tree_cb(
entry->path = git_buf_detach(&path); entry->path = git_buf_detach(&path);
git_buf_free(&path); git_buf_free(&path);
if (git_vector_insert(&data->index->entries, entry) < 0) { if (git_vector_insert(data->new_entries, entry) < 0) {
index_entry_free(entry); index_entry_free(entry);
return -1; return -1;
} }
...@@ -2022,22 +2016,22 @@ int git_index_read_tree(git_index *index, const git_tree *tree) ...@@ -2022,22 +2016,22 @@ int git_index_read_tree(git_index *index, const git_tree *tree)
git_vector entries = GIT_VECTOR_INIT; git_vector entries = GIT_VECTOR_INIT;
read_tree_data data; read_tree_data data;
git_vector_sort(&index->entries); git_vector_set_cmp(&entries, index->entries._cmp); /* match sort */
git_vector_set_cmp(&entries, index->entries._cmp);
git_vector_swap(&entries, &index->entries);
git_index_clear(index); data.old_entries = &index->entries;
data.new_entries = &entries;
data.entries_search = index->entries_search;
data.index = index; git_vector_sort(&index->entries);
data.old_entries = &entries;
error = git_tree_walk(tree, GIT_TREEWALK_POST, read_tree_cb, &data); error = git_tree_walk(tree, GIT_TREEWALK_POST, read_tree_cb, &data);
index_entries_free(&entries); git_vector_sort(&entries);
git_vector_free(&entries);
git_vector_sort(&index->entries); git_index_clear(index);
git_vector_swap(&entries, &index->entries);
git_vector_free(&entries);
return error; return error;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment