Some memory leak fixes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
diff --git a/src/attrcache.c b/src/attrcache.c
index 925abb5..88b68eb 100644
--- a/src/attrcache.c
+++ b/src/attrcache.c
@@ -121,7 +121,6 @@ static int attr_cache_remove(git_attr_cache *cache, git_attr_file *file)
{
int error = 0;
git_attr_file_entry *entry;
- bool found = false;
if (!file)
return 0;
@@ -133,7 +132,7 @@ static int attr_cache_remove(git_attr_cache *cache, git_attr_file *file)
attr_cache_unlock(cache);
- if (found) {
+ if (file) {
GIT_REFCOUNT_OWN(file, NULL);
git_attr_file__free(file);
}
@@ -206,39 +205,42 @@ int git_attr_cache__get(
int error = 0;
git_attr_cache *cache = git_repository_attr_cache(repo);
git_attr_file_entry *entry = NULL;
- git_attr_file *file = NULL;
+ git_attr_file *file = NULL, *updated = NULL;
if ((error = attr_cache_lookup(
&file, &entry, repo, source, base, filename)) < 0)
- goto cleanup;
-
- /* if file not found or out of date, load up-to-date data and replace */
- if (!file || (error = git_attr_file__out_of_date(repo, file)) > 0) {
- /* decrement refcount (if file was found) b/c we will not return it */
- git_attr_file__free(file);
+ return error;
- if (!(error = git_attr_file__load(&file, repo, entry, source, parser)))
- error = attr_cache_upsert(cache, file);
+ /* load file if we don't have one or if existing one is out of date */
+ if (!file || (error = git_attr_file__out_of_date(repo, file)) > 0)
+ error = git_attr_file__load(&updated, repo, entry, source, parser);
+
+ /* if we loaded the file, insert into and/or update cache */
+ if (updated) {
+ if ((error = attr_cache_upsert(cache, updated)) < 0)
+ git_attr_file__free(updated);
+ else {
+ git_attr_file__free(file); /* offset incref from lookup */
+ file = updated;
+ }
}
- /* GIT_ENOTFOUND is okay when probing for the file. If the file did
- * exist and now does not, we have to remove it from cache, however.
- */
- if (error == GIT_ENOTFOUND) {
- giterr_clear();
- error = 0;
-
- if (file != NULL)
- error = attr_cache_remove(cache, file);
+ /* if file could not be loaded */
+ if (error < 0) {
+ /* remove existing entry */
+ if (file) {
+ git_attr_file__free(file); /* offset incref from lookup */
+ attr_cache_remove(cache, file);
+ file = NULL;
+ }
+ /* no error if file simply doesn't exist */
+ if (error == GIT_ENOTFOUND) {
+ giterr_clear();
+ error = 0;
+ }
}
-cleanup:
- if (error < 0 && file != NULL) {
- git_attr_file__free(file);
- file = NULL;
- }
*out = file;
-
return error;
}
diff --git a/tests/threads/diff.c b/tests/threads/diff.c
index d33e75f..79b8580 100644
--- a/tests/threads/diff.c
+++ b/tests/threads/diff.c
@@ -103,6 +103,7 @@ static void *run_index_diffs(void *arg)
}
git_diff_free(diff);
+ giterr_clear();
return arg;
}
@@ -139,8 +140,7 @@ static void *run_index_diffs_with_modifier(void *arg)
git_thread_yield();
}
- git_index_free(idx);
- return arg;
+ goto done;
}
/* only use explicit index in this test to prevent reloading */
@@ -164,7 +164,10 @@ static void *run_index_diffs_with_modifier(void *arg)
/* results will be unpredictable with index modifier thread running */
git_diff_free(diff);
+
+done:
git_index_free(idx);
+ giterr_clear();
return arg;
}
diff --git a/tests/threads/iterator.c b/tests/threads/iterator.c
index 4dd251f..8aeae1a 100644
--- a/tests/threads/iterator.c
+++ b/tests/threads/iterator.c
@@ -11,7 +11,7 @@ void test_threads_iterator__cleanup(void)
static void *run_workdir_iterator(void *arg)
{
- int error = 0, thread = *(int *)arg;
+ int error = 0;
git_iterator *iter;
const git_index_entry *entry = NULL;
@@ -35,7 +35,7 @@ static void *run_workdir_iterator(void *arg)
cl_assert_equal_i(GIT_ITEROVER, error);
git_iterator_free(iter);
-
+ giterr_clear();
return arg;
}
diff --git a/tests/threads/refdb.c b/tests/threads/refdb.c
index fbf6ac0..3b35b45 100644
--- a/tests/threads/refdb.c
+++ b/tests/threads/refdb.c
@@ -37,6 +37,7 @@ static void *iterate_refs(void *arg)
git_reference_iterator_free(i);
+ giterr_clear();
return arg;
}
@@ -115,6 +116,7 @@ static void *create_refs(void *arg)
for (i = 0; i < 10; ++i)
git_reference_free(ref[i]);
+ giterr_clear();
return arg;
}
@@ -141,6 +143,7 @@ static void *delete_refs(void *arg)
}
}
+ giterr_clear();
return arg;
}