diff options
| author | Vicent Marti <tanoku@gmail.com> | 2011-02-28 16:51:17 +0200 |
|---|---|---|
| committer | Vicent Marti <tanoku@gmail.com> | 2011-03-03 20:23:52 +0200 |
| commit | 48c27f86bbe9678c7e01a90a2cec7a30327b0e90 (patch) | |
| tree | 0156ea823de82477792ad4778378200eee28aee3 /src/repository.c | |
| parent | 86d7e1ca6f54161a9e4d1ebe7a2f8e4802dc9639 (diff) | |
| download | libgit2-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.c | 29 |
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); |
