GKeyFile: Add refcounting API
authorChristian Persch <chpe@gnome.org>
Mon, 25 May 2009 13:07:27 +0000 (15:07 +0200)
committerMatthias Clasen <mclasen@redhat.com>
Sat, 15 Oct 2011 21:44:45 +0000 (17:44 -0400)
Adds g_key_file_ref and g_key_file_unref, to be used by a future
GKeyFile boxed type for language bindings.

Based on the patch by Christian Persch and Emmanuele Bassi.

Author: Christian Persch
Signed-off-by: Johan Dahlin
Signed-off-by: Giovanni Campagna
https://bugzilla.gnome.org/show_bug.cgi?id=590808

docs/reference/glib/glib-sections.txt
glib/gkeyfile.c
glib/gkeyfile.h
glib/glib.symbols

index c6b517a..d20a65b 100644 (file)
@@ -1807,6 +1807,8 @@ GKeyFileFlags
 <SUBSECTION>
 g_key_file_new
 g_key_file_free
+g_key_file_ref
+g_key_file_unref
 g_key_file_set_list_separator
 g_key_file_load_from_file
 g_key_file_load_from_data
index ad8cdae..2138341 100644 (file)
@@ -446,6 +446,8 @@ struct _GKeyFile
   GKeyFileFlags flags;
 
   gchar **locales;
+
+  volatile gint ref_count;
 };
 
 typedef struct _GKeyFileKeyValuePair GKeyFileKeyValuePair;
@@ -602,8 +604,11 @@ g_key_file_clear (GKeyFile *key_file)
       g_key_file_remove_group_node (key_file, group_node);
     }
 
-  g_hash_table_destroy (key_file->group_hash);
-  key_file->group_hash = NULL;
+  if (key_file->group_hash != NULL)
+    {
+      g_hash_table_destroy (key_file->group_hash);
+      key_file->group_hash = NULL;
+    }
 
   g_warn_if_fail (key_file->groups == NULL);
 }
@@ -627,6 +632,7 @@ g_key_file_new (void)
   GKeyFile *key_file;
 
   key_file = g_slice_new0 (GKeyFile);
+  key_file->ref_count = 1;
   g_key_file_init (key_file);
 
   return key_file;
@@ -1055,10 +1061,32 @@ g_key_file_load_from_data_dirs (GKeyFile       *key_file,
 }
 
 /**
+ * g_key_file_ref:
+ * @key_file: a #GKeyFile
+ *
+ * Increases the reference count of @key_file.
+ *
+ * Returns: the same @key_file.
+ *
+ * Since: 2.32
+ **/
+GKeyFile *
+g_key_file_ref (GKeyFile *key_file)
+{
+  g_return_val_if_fail (key_file != NULL, NULL);
+
+  g_atomic_int_inc (&key_file->ref_count);
+
+  return key_file;
+}
+
+/**
  * g_key_file_free:
  * @key_file: a #GKeyFile
  *
- * Frees a #GKeyFile.
+ * Clears all keys and groups from @key_file, and decreases the
+ * reference count by 1. If the reference count reaches zero,
+ * frees the key file and all its allocated memory.
  *
  * Since: 2.6
  **/
@@ -1066,9 +1094,30 @@ void
 g_key_file_free (GKeyFile *key_file)
 {
   g_return_if_fail (key_file != NULL);
-  
+
   g_key_file_clear (key_file);
-  g_slice_free (GKeyFile, key_file);
+  g_key_file_unref (key_file);
+}
+
+/**
+ * g_key_file_unref:
+ * @key_file: a #GKeyFile
+ *
+ * Decreases the reference count of @key_file by 1. If the reference count
+ * reaches zero, frees the key file and all its allocated memory.
+ *
+ * Since: 2.32
+ **/
+void
+g_key_file_unref (GKeyFile *key_file)
+{
+  g_return_if_fail (key_file != NULL);
+
+  if (g_atomic_int_dec_and_test (&key_file->ref_count))
+    {
+      g_key_file_clear (key_file);
+      g_slice_free (GKeyFile, key_file);
+    }
 }
 
 /* If G_KEY_FILE_KEEP_TRANSLATIONS is not set, only returns
index 6b38708..998bb7a 100644 (file)
@@ -55,6 +55,8 @@ typedef enum
 } GKeyFileFlags;
 
 GKeyFile *g_key_file_new                    (void);
+GKeyFile *g_key_file_ref                    (GKeyFile             *key_file);
+void      g_key_file_unref                  (GKeyFile             *key_file);
 void      g_key_file_free                   (GKeyFile             *key_file);
 void      g_key_file_set_list_separator     (GKeyFile             *key_file,
                                             gchar                 separator);
index fc02b14..c78d1f8 100644 (file)
@@ -480,6 +480,8 @@ g_io_channel_win32_poll
 g_io_channel_win32_set_debug
 #endif
 g_key_file_error_quark
+g_key_file_ref
+g_key_file_unref
 g_key_file_free
 g_key_file_get_boolean
 g_key_file_get_boolean_list