|
|
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 |
|