Commit 123e5963e169c160034b19a3d9df60f65cfa09a8

Patrick Steinhardt 2018-08-10T18:59:59

config_entries: abstract away reference counting Instead of directly calling `git_atomic_inc` in users of the config entries store, provide a `git_config_entries_incref` function to further decouple the interfaces. Convert the refcount to a `git_refcount` structure while at it.

diff --git a/src/config_entries.c b/src/config_entries.c
index ef05d7f..5782fab 100644
--- a/src/config_entries.c
+++ b/src/config_entries.c
@@ -44,8 +44,7 @@ int git_config_entries_new(git_config_entries **out)
 
 	entries = git__calloc(1, sizeof(git_config_entries));
 	GITERR_CHECK_ALLOC(entries);
-
-	git_atomic_set(&entries->refcount, 1);
+	GIT_REFCOUNT_INC(entries);
 
 	if ((error = git_strmap_alloc(&entries->map)) < 0)
 		git__free(entries);
@@ -55,15 +54,14 @@ int git_config_entries_new(git_config_entries **out)
 	return error;
 }
 
-void git_config_entries_free(git_config_entries *entries)
+void git_config_entries_incref(git_config_entries *entries)
 {
-	config_entry_list *list = NULL, *next;
-
-	if (!entries)
-		return;
+	GIT_REFCOUNT_INC(entries);
+}
 
-	if (git_atomic_dec(&entries->refcount) != 0)
-		return;
+static void config_entries_free(git_config_entries *entries)
+{
+	config_entry_list *list = NULL, *next;
 
 	git_strmap_foreach_value(entries->map, list, config_entry_list_free(list));
 	git_strmap_free(entries->map);
@@ -78,6 +76,12 @@ void git_config_entries_free(git_config_entries *entries)
 	git__free(entries);
 }
 
+void git_config_entries_free(git_config_entries *entries)
+{
+	if (entries)
+		GIT_REFCOUNT_DEC(entries, config_entries_free);
+}
+
 int git_config_entries_append(git_config_entries *entries, git_config_entry *entry)
 {
 	git_strmap_iter pos;
diff --git a/src/config_entries.h b/src/config_entries.h
index 674b7a8..5ee5d4e 100644
--- a/src/config_entries.h
+++ b/src/config_entries.h
@@ -17,12 +17,13 @@ typedef struct config_entry_list {
 } config_entry_list;
 
 typedef struct {
-	git_atomic refcount;
+	git_refcount rc;
 	git_strmap *map;
 	config_entry_list *list;
 } git_config_entries;
 
 int git_config_entries_new(git_config_entries **out);
+void git_config_entries_incref(git_config_entries *entries);
 void git_config_entries_free(git_config_entries *entries);
 /* Add or append the new config option */
 int git_config_entries_append(git_config_entries *entries, git_config_entry *entry);
diff --git a/src/config_file.c b/src/config_file.c
index 8c05fd9..7a7f35f 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -88,7 +88,7 @@ static git_config_entries *diskfile_entries_take(diskfile_header *h)
 	}
 
 	entries = h->entries;
-	git_atomic_inc(&entries->refcount);
+	git_config_entries_incref(entries);
 
 	git_mutex_unlock(&h->values_mutex);