Blame SOURCES/0001-DConfChangeset-expose-concept-of-sealing.patch

ff660f
From 40f887db43dc89e546ecef9c2d2f31a61858badc Mon Sep 17 00:00:00 2001
ff660f
From: Ryan Lortie <desrt@desrt.ca>
ff660f
Date: Tue, 25 Jun 2013 14:39:26 -0400
ff660f
Subject: [PATCH 1/2] DConfChangeset: expose concept of "sealing"
ff660f
ff660f
DConfChangeset is a partially threadsafe type.
ff660f
ff660f
when first created, it is mutable and can only be used from one thread.
ff660f
After it is filled in, the intention is that it can be shared between
ff660f
threads as long as it isn't changed.
ff660f
ff660f
Previously, this transition was made when dconf_changeset_describe() was
ff660f
called.  After that, it was not possible to make any more changes.
ff660f
ff660f
Formalise and document this concept and add an explicit call for it:
ff660f
dconf_changeset_seal().
ff660f
ff660f
https://bugzilla.gnome.org/show_bug.cgi?id=703073
ff660f
---
ff660f
 common/dconf-changeset.c | 49 ++++++++++++++++++++++++++++++++++++++++++------
ff660f
 common/dconf-changeset.h |  2 ++
ff660f
 2 files changed, 45 insertions(+), 6 deletions(-)
ff660f
ff660f
diff --git a/common/dconf-changeset.c b/common/dconf-changeset.c
ff660f
index d9b9f41..54be719 100644
ff660f
--- a/common/dconf-changeset.c
ff660f
+++ b/common/dconf-changeset.c
ff660f
@@ -54,7 +54,8 @@
ff660f
 struct _DConfChangeset
ff660f
 {
ff660f
   GHashTable *table;
ff660f
-  gboolean is_database;
ff660f
+  guint is_database : 1;
ff660f
+  guint is_sealed : 1;
ff660f
   gint ref_count;
ff660f
 
ff660f
   gchar *prefix;
ff660f
@@ -195,7 +196,7 @@ dconf_changeset_set (DConfChangeset *changeset,
ff660f
                      const gchar    *path,
ff660f
                      GVariant       *value)
ff660f
 {
ff660f
-  g_return_if_fail (changeset->prefix == NULL);
ff660f
+  g_return_if_fail (!changeset->is_sealed);
ff660f
   g_return_if_fail (dconf_is_path (path, NULL));
ff660f
 
ff660f
   /* Check if we are performing a path reset */
ff660f
@@ -366,12 +367,44 @@ dconf_changeset_string_ptr_compare (gconstpointer a_p,
ff660f
   return strcmp (*a, *b);
ff660f
 }
ff660f
 
ff660f
-static void
ff660f
-dconf_changeset_build_description (DConfChangeset *changeset)
ff660f
+/**
ff660f
+ * dconf_changeset_seal:
ff660f
+ * @changeset: a #DConfChangeset
ff660f
+ *
ff660f
+ * Seals @changeset.
ff660f
+ *
ff660f
+ * When a #DConfChangeset is first created, it is mutable and
ff660f
+ * non-threadsafe.  Once the changeset is populated with the required
ff660f
+ * changes, it can be shared between multiple threads, but only by
ff660f
+ * making it immutable by "sealing" it.
ff660f
+ *
ff660f
+ * After the changeset is sealed, you cannot call dconf_changeset_set()
ff660f
+ * or any other functions that would modify it.  It is safe, however, to
ff660f
+ * share it between multiple threads.
ff660f
+ *
ff660f
+ * All changesets are unsealed on creation, including those that are
ff660f
+ * made by copying changesets that are sealed.
ff660f
+ * dconf_changeset_describe() will implicitly seal a changeset.
ff660f
+ *
ff660f
+ * This function is idempotent.
ff660f
+ *
ff660f
+ * Since: 0.18
ff660f
+ **/
ff660f
+void
ff660f
+dconf_changeset_seal (DConfChangeset *changeset)
ff660f
 {
ff660f
   gsize prefix_length;
ff660f
   gint n_items;
ff660f
 
ff660f
+  if (changeset->is_sealed)
ff660f
+    return;
ff660f
+
ff660f
+  changeset->is_sealed = TRUE;
ff660f
+
ff660f
+  /* This function used to be called dconf_changeset_build_description()
ff660f
+   * because that's basically what sealing is...
ff660f
+   */
ff660f
+
ff660f
   n_items = g_hash_table_size (changeset->table);
ff660f
 
ff660f
   /* If there are no items then what is there to describe? */
ff660f
@@ -501,6 +534,9 @@ dconf_changeset_build_description (DConfChangeset *changeset)
ff660f
  * The @paths array is returned in an order such that dir will always
ff660f
  * come before keys contained within those dirs.
ff660f
  *
ff660f
+ * If @changeset is not already sealed then this call will implicitly
ff660f
+ * seal it.  See dconf_changeset_seal().
ff660f
+ *
ff660f
  * Returns: the number of changes (the length of @changes and @values).
ff660f
  **/
ff660f
 guint
ff660f
@@ -513,8 +549,7 @@ dconf_changeset_describe (DConfChangeset       *changeset,
ff660f
 
ff660f
   n_items = g_hash_table_size (changeset->table);
ff660f
 
ff660f
-  if (n_items && !changeset->prefix)
ff660f
-    dconf_changeset_build_description (changeset);
ff660f
+  dconf_changeset_seal (changeset);
ff660f
 
ff660f
   if (prefix)
ff660f
     *prefix = changeset->prefix;
ff660f
@@ -664,6 +699,8 @@ dconf_changeset_change (DConfChangeset *changeset,
ff660f
   gsize prefix_len;
ff660f
   gint i;
ff660f
 
ff660f
+  g_return_if_fail (!changeset->is_sealed);
ff660f
+
ff660f
   /* Handling resets is a little bit tricky...
ff660f
    *
ff660f
    * Consider the case that we have @changeset containing a key /a/b and
ff660f
diff --git a/common/dconf-changeset.h b/common/dconf-changeset.h
ff660f
index 7228105..8a9cb48 100644
ff660f
--- a/common/dconf-changeset.h
ff660f
+++ b/common/dconf-changeset.h
ff660f
@@ -70,4 +70,6 @@ void                    dconf_changeset_change                          (DConfCh
ff660f
 DConfChangeset *        dconf_changeset_diff                            (DConfChangeset           *from,
ff660f
                                                                          DConfChangeset           *to);
ff660f
 
ff660f
+void                    dconf_changeset_seal                            (DConfChangeset           *changeset);
ff660f
+
ff660f
 #endif /* __dconf_changeset_h__ */
ff660f
-- 
ff660f
1.8.3.1
ff660f