index: release the snapshot instead of freeing the index#4803
index: release the snapshot instead of freeing the index#4803pks-t merged 3 commits intolibgit2:masterfrom
Conversation
Previously we would assert in index_free because the reader incrementation would not be balanced. Release the snapshot normally, so the variable gets decremented before the index is freed.
|
Fixes half of it, anyway - we need to not |
|
/rebuild |
|
Okay, @ethomson, I started to rebuild this pull request. |
|
(That wasn't meant as snark, BTW, I just meant that we need to not close the issue after merging this.) |
|
I was under the impression that Would it be acceptable to just |
|
Fixed the |
src/vector.c
Outdated
|
|
||
| memcpy(v->contents, src->contents, bytes); | ||
| GITERR_CHECK_ALLOC_MULTIPLY(&bytes, src->length, sizeof(void *)); | ||
| if (bytes != 0) { |
There was a problem hiding this comment.
if (src->length) {
size_t bytes;
GITERR_CHECKALLOC_MULTIPLY(&bytes, src->length, sizeof(void *));
...
}
No need to do unnecessary work in case where src->length is already 0. I think like this intentions also become a bit clearer.
There was a problem hiding this comment.
Fixed. I was attempting to remove the different codepaths when duping vs a normal init (ie. make dup go through init/resize/memcpy instead of doing its own malloc), but I don't think it's worthwhile.
| GITERR_CHECK_ALLOC_MULTIPLY(&bytes, src->length, sizeof(void *)); | ||
| v->contents = git__malloc(bytes); | ||
| GITERR_CHECK_ALLOC(v->contents); | ||
| v->_alloc_size = src->length; |
There was a problem hiding this comment.
Jeez, this _alloc_size member is really confusing. One tends to think it is the actual size (as you also seem to have interpreted it in your first go), but it actually is the allocated length. We should probably refactor this in another PR
| void *new_contents; | ||
|
|
||
| if (new_size == 0) | ||
| return 0; |
There was a problem hiding this comment.
One might tend to think that resizing to 0 might mean that we should deallocate the vector. But resize_vector is only called from git_vector_init, git_vector_insert, git_vector_insert_sorted, git_vector_insert_null, git_vector_size_hint and git_vector_resize_to. Only for the last two it might make sense to do the deallocation dance, though.
git_vector_resize_tois only used ingit_vector_set, so the deallocation path could never be hit here.git_vector_size_hintwill only do any work if the new size hint is bigger thanalloc_size. So it also cannot ever hit the deallocation path.
So the dealloc would in fact be useless.
I think the only code path that can actually invoke resize_vector(v, 0) is git_vector_size_hint. And I can imagine a caller trivially invoking it e.g. if he wants to allocate a vector for a set of n items, where n might also be 0.
Anyway, long story short: makes sense to me.
|
Thanks @tiennou! |
Previously we would assert in index_free because the reader incrementation would not be balanced. Release the snapshot normally, so the variable gets decremented before the index is freed.
Fixes #4802.