[glib] GSettings delayed: fix handling of mandatory keys



commit e06e441ac23f3752f252e86e1d930678de53c778
Author: Ryan Lortie <desrt desrt ca>
Date:   Sat Apr 17 11:39:04 2010 -0400

    GSettings delayed: fix handling of mandatory keys
    
      - if a key becomes mandatory, drop it from the changeset
    
      - if we still get failing writes (ie: because of a race) then drop the
        entire changeset and signal that it happened

 gio/gdelayedsettingsbackend.c |   61 +++++++++++++++++++++++++++++++++++-----
 1 files changed, 53 insertions(+), 8 deletions(-)
---
diff --git a/gio/gdelayedsettingsbackend.c b/gio/gdelayedsettingsbackend.c
index 505a85b..890c93f 100644
--- a/gio/gdelayedsettingsbackend.c
+++ b/gio/gdelayedsettingsbackend.c
@@ -158,12 +158,18 @@ g_delayed_settings_backend_apply (GDelayedSettingsBackend *delayed)
 {
   if (g_tree_nnodes (delayed->priv->delayed) > 0)
     {
+      gboolean success;
       GTree *tmp;
 
       tmp = delayed->priv->delayed;
       delayed->priv->delayed = g_settings_backend_create_tree ();
-      g_settings_backend_write_keys (delayed->priv->backend,
-                                     tmp, delayed->priv);
+      success = g_settings_backend_write_keys (delayed->priv->backend,
+                                               tmp, delayed->priv);
+
+      if (!success)
+        g_settings_backend_changed_tree (G_SETTINGS_BACKEND (delayed),
+                                         tmp, NULL);
+
       g_tree_unref (tmp);
 
       if (delayed->priv->owner)
@@ -236,22 +242,61 @@ delayed_backend_writable_changed (GSettingsBackend *backend,
 {
   GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (user_data);
 
-  /* XXX: maybe drop keys from the delayed-apply settings
-   *      if they became non-writable?
-   */
+  if (g_tree_lookup (delayed->priv->delayed, key) &&
+      !g_settings_backend_get_writable (delayed->priv->backend, key))
+    {
+      /* drop the key from our changeset if it just became read-only.
+       * no need to signal this since the writable change implies it.
+       */
+      g_tree_remove (delayed->priv->delayed, key);
+    }
+
   g_settings_backend_writable_changed (G_SETTINGS_BACKEND (delayed), key);
 }
 
+/* slow method until we get foreach-with-remove in GTree
+ */
+typedef struct
+{
+  const gchar *path;
+  const gchar **keys;
+  gsize index;
+} CheckPrefixState;
+
+static gboolean
+check_prefix (gpointer key,
+              gpointer value,
+              gpointer data)
+{
+  CheckPrefixState *state = data;
+
+  if (g_str_has_prefix (key, state->path))
+    state->keys[state->index++] = key;
+
+  return FALSE;
+}
+
 static void
 delayed_backend_path_writable_changed (GSettingsBackend *backend,
                                        const gchar      *path,
                                        gpointer          user_data)
 {
   GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (user_data);
+  CheckPrefixState state = { path, };
+  gsize i;
+
+  /* collect a list of possibly-affected keys (ie: matching the path) */
+  state.keys = g_new (const gchar *, g_tree_nnodes (delayed->priv->delayed));
+  g_tree_foreach (delayed->priv->delayed, check_prefix, &state);
+
+  /* drop the keys that have been affected */
+  for (i = 0; i < state.index; i++)
+    if (!g_settings_backend_get_writable (delayed->priv->backend,
+                                          state.keys[i]))
+      g_tree_remove (delayed->priv->delayed, state.keys[i]);
+
+  g_free (state.keys);
 
-  /* XXX: maybe drop keys from the delayed-apply settings
-   *      if they became non-writable?
-   */
   g_settings_backend_path_writable_changed (G_SETTINGS_BACKEND (delayed),
                                             path);
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]