summaryrefslogtreecommitdiff
path: root/src/repository.c
diff options
context:
space:
mode:
authorVicent Marti <tanoku@gmail.com>2011-02-28 16:51:17 +0200
committerVicent Marti <tanoku@gmail.com>2011-03-03 20:23:52 +0200
commit48c27f86bbe9678c7e01a90a2cec7a30327b0e90 (patch)
tree0156ea823de82477792ad4778378200eee28aee3 /src/repository.c
parent86d7e1ca6f54161a9e4d1ebe7a2f8e4802dc9639 (diff)
downloadlibgit2-48c27f86bbe9678c7e01a90a2cec7a30327b0e90.tar.gz
Implement reference counting for git_objects
All `git_object` instances looked up from the repository are reference counted. User is expected to use the new `git_object_close` when an object is no longer needed to force freeing it. Signed-off-by: Vicent Marti <tanoku@gmail.com>
Diffstat (limited to 'src/repository.c')
-rw-r--r--src/repository.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/src/repository.c b/src/repository.c
index 77ce0c0f4..9f27a38e8 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -209,6 +209,13 @@ static git_repository *repository_alloc()
return NULL;
}
+ if (git_vector_init(&repo->memory_objects, 16, NULL) < GIT_SUCCESS) {
+ git_hashtable_free(repo->objects);
+ git_repository__refcache_free(&repo->references);
+ free(repo);
+ return NULL;
+ }
+
return repo;
}
@@ -328,7 +335,8 @@ int git_repository_open(git_repository **repo_out, const char *path)
void git_repository_free(git_repository *repo)
{
git_object *object;
- const git_oid *oid;
+ const void *_unused;
+ unsigned int i;
if (repo == NULL)
return;
@@ -338,11 +346,24 @@ void git_repository_free(git_repository *repo)
free(repo->path_repository);
free(repo->path_odb);
- GIT_HASHTABLE_FOREACH(repo->objects, oid, object, {
- git_object_free(object);
- });
+ /* Increment the refcount of all the objects in the repository
+ * to prevent freeing dependencies */
+ GIT_HASHTABLE_FOREACH(repo->objects, _unused, object,
+ GIT_OBJECT_INCREF(object);
+ );
+
+ /* force free all the objects */
+ GIT_HASHTABLE_FOREACH(repo->objects, _unused, object,
+ git_object__free(object);
+ );
+
+ for (i = 0; i < repo->memory_objects.length; ++i) {
+ object = git_vector_get(&repo->memory_objects, i);
+ git_object__free(object);
+ }
git_hashtable_free(repo->objects);
+ git_vector_free(&repo->memory_objects);
git_repository__refcache_free(&repo->references);