X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgdelayedsettingsbackend.c;h=22a42ebdaeed409c28f7e9e4e7f1835a69ca42a3;hb=9da85c7262325478e8730ae9f3e76bd0528a9a8c;hp=dce1d7d78e256d0dd2c90423b877ac14ca9c6d7d;hpb=73ca8b47540d005d5227c03aac143d6780da654c;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gdelayedsettingsbackend.c b/gio/gdelayedsettingsbackend.c index dce1d7d..22a42eb 100644 --- a/gio/gdelayedsettingsbackend.c +++ b/gio/gdelayedsettingsbackend.c @@ -12,9 +12,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library; if not, see . * * Author: Ryan Lortie */ @@ -30,16 +28,16 @@ struct _GDelayedSettingsBackendPrivate { GSettingsBackend *backend; - GStaticMutex lock; + GMutex lock; GTree *delayed; GMainContext *owner_context; gpointer owner; }; -G_DEFINE_TYPE (GDelayedSettingsBackend, - g_delayed_settings_backend, - G_TYPE_SETTINGS_BACKEND) +G_DEFINE_TYPE_WITH_PRIVATE (GDelayedSettingsBackend, + g_delayed_settings_backend, + G_TYPE_SETTINGS_BACKEND) static gboolean invoke_notify_unapplied (gpointer data) @@ -56,7 +54,7 @@ g_delayed_settings_backend_notify_unapplied (GDelayedSettingsBackend *delayed) GMainContext *target_context; GObject *target; - g_static_mutex_lock (&delayed->priv->lock); + g_mutex_lock (&delayed->priv->lock); if (delayed->priv->owner) { target_context = delayed->priv->owner_context; @@ -67,7 +65,7 @@ g_delayed_settings_backend_notify_unapplied (GDelayedSettingsBackend *delayed) target_context = NULL; target = NULL; } - g_static_mutex_unlock (&delayed->priv->lock); + g_mutex_unlock (&delayed->priv->lock); if (target != NULL) g_main_context_invoke (target_context, invoke_notify_unapplied, target); @@ -85,7 +83,7 @@ g_delayed_settings_backend_read (GSettingsBackend *backend, if (!default_value) { - g_static_mutex_lock (&delayed->priv->lock); + g_mutex_lock (&delayed->priv->lock); if (g_tree_lookup_extended (delayed->priv->delayed, key, NULL, &result)) { /* NULL in the tree means we should consult the default value */ @@ -94,7 +92,7 @@ g_delayed_settings_backend_read (GSettingsBackend *backend, else default_value = TRUE; } - g_static_mutex_unlock (&delayed->priv->lock); + g_mutex_unlock (&delayed->priv->lock); } if (result == NULL) @@ -104,6 +102,32 @@ g_delayed_settings_backend_read (GSettingsBackend *backend, return result; } +static GVariant * +g_delayed_settings_backend_read_user_value (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + gboolean value_found = FALSE; + gpointer result = NULL; + + /* If we find an explicit NULL in our changeset then we want to return + * NULL (because the user value has been reset). + * + * Otherwise, chain up. + */ + g_mutex_lock (&delayed->priv->lock); + value_found = g_tree_lookup_extended (delayed->priv->delayed, key, NULL, &result); + if (result) + g_variant_ref (result); + g_mutex_unlock (&delayed->priv->lock); + + if (value_found) + return result; + + return g_settings_backend_read_user_value (delayed->priv->backend, key, expected_type); +} + static gboolean g_delayed_settings_backend_write (GSettingsBackend *backend, const gchar *key, @@ -113,11 +137,11 @@ g_delayed_settings_backend_write (GSettingsBackend *backend, GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); gboolean was_empty; - g_static_mutex_lock (&delayed->priv->lock); + g_mutex_lock (&delayed->priv->lock); was_empty = g_tree_nnodes (delayed->priv->delayed) == 0; g_tree_insert (delayed->priv->delayed, g_strdup (key), g_variant_ref_sink (value)); - g_static_mutex_unlock (&delayed->priv->lock); + g_mutex_unlock (&delayed->priv->lock); g_settings_backend_changed (backend, key, origin_tag); @@ -144,11 +168,11 @@ g_delayed_settings_backend_write_tree (GSettingsBackend *backend, GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); gboolean was_empty; - g_static_mutex_lock (&delayed->priv->lock); + g_mutex_lock (&delayed->priv->lock); was_empty = g_tree_nnodes (delayed->priv->delayed) == 0; g_tree_foreach (tree, add_to_tree, delayed->priv->delayed); - g_static_mutex_unlock (&delayed->priv->lock); + g_mutex_unlock (&delayed->priv->lock); g_settings_backend_changed_tree (backend, tree, origin_tag); @@ -175,10 +199,10 @@ g_delayed_settings_backend_reset (GSettingsBackend *backend, GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); gboolean was_empty; - g_static_mutex_lock (&delayed->priv->lock); + g_mutex_lock (&delayed->priv->lock); was_empty = g_tree_nnodes (delayed->priv->delayed) == 0; g_tree_insert (delayed->priv->delayed, g_strdup (key), NULL); - g_static_mutex_unlock (&delayed->priv->lock); + g_mutex_unlock (&delayed->priv->lock); if (was_empty) g_delayed_settings_backend_notify_unapplied (delayed); @@ -229,12 +253,12 @@ g_delayed_settings_backend_apply (GDelayedSettingsBackend *delayed) gboolean success; GTree *tmp; - g_static_mutex_lock (&delayed->priv->lock); + g_mutex_lock (&delayed->priv->lock); tmp = delayed->priv->delayed; delayed->priv->delayed = g_settings_backend_create_tree (); success = g_settings_backend_write_tree (delayed->priv->backend, tmp, delayed->priv); - g_static_mutex_unlock (&delayed->priv->lock); + g_mutex_unlock (&delayed->priv->lock); if (!success) g_settings_backend_changed_tree (G_SETTINGS_BACKEND (delayed), @@ -253,10 +277,10 @@ g_delayed_settings_backend_revert (GDelayedSettingsBackend *delayed) { GTree *tmp; - g_static_mutex_lock (&delayed->priv->lock); + g_mutex_lock (&delayed->priv->lock); tmp = delayed->priv->delayed; delayed->priv->delayed = g_settings_backend_create_tree (); - g_static_mutex_unlock (&delayed->priv->lock); + g_mutex_unlock (&delayed->priv->lock); g_settings_backend_changed_tree (G_SETTINGS_BACKEND (delayed), tmp, NULL); g_tree_unref (tmp); @@ -282,8 +306,8 @@ static void delayed_backend_keys_changed (GObject *target, GSettingsBackend *backend, const gchar *path, - const gchar * const *items, - gpointer origin_tag) + gpointer origin_tag, + const gchar * const *items) { GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (target); @@ -313,13 +337,18 @@ delayed_backend_writable_changed (GObject *target, GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (target); gboolean last_one = FALSE; - g_static_mutex_lock (&delayed->priv->lock); + g_mutex_lock (&delayed->priv->lock); - if (g_tree_lookup (delayed->priv->delayed, key) && + if (g_tree_lookup (delayed->priv->delayed, key) != NULL && !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 since the writable change below implies it. + * + * note that the item in the tree may very well be set to NULL in + * the case that the user stored a reset. we intentionally don't + * drop the key in this case since a reset will always succeed + * (even against a non-writable key). */ g_tree_remove (delayed->priv->delayed, key); @@ -327,7 +356,7 @@ delayed_backend_writable_changed (GObject *target, last_one = g_tree_nnodes (delayed->priv->delayed) == 0; } - g_static_mutex_unlock (&delayed->priv->lock); + g_mutex_unlock (&delayed->priv->lock); if (last_one) g_delayed_settings_backend_notify_unapplied (delayed); @@ -366,7 +395,7 @@ delayed_backend_path_writable_changed (GObject *target, gboolean last_one = FALSE; gsize n_keys; - g_static_mutex_lock (&delayed->priv->lock); + g_mutex_lock (&delayed->priv->lock); n_keys = g_tree_nnodes (delayed->priv->delayed); @@ -378,9 +407,12 @@ delayed_backend_path_writable_changed (GObject *target, /* collect a list of possibly-affected keys (ie: matching the path) */ g_tree_foreach (delayed->priv->delayed, check_prefix, &state); - /* drop the keys that have been affected */ + /* drop the keys that have been affected. + * + * don't drop 'reset' keys (see above) */ for (i = 0; i < state.index; i++) - if (!g_settings_backend_get_writable (delayed->priv->backend, + if (g_tree_lookup (delayed->priv->delayed, state.keys[i]) != NULL && + !g_settings_backend_get_writable (delayed->priv->backend, state.keys[i])) g_tree_remove (delayed->priv->delayed, state.keys[i]); @@ -389,7 +421,7 @@ delayed_backend_path_writable_changed (GObject *target, last_one = g_tree_nnodes (delayed->priv->delayed) == 0; } - g_static_mutex_unlock (&delayed->priv->lock); + g_mutex_unlock (&delayed->priv->lock); if (last_one) g_delayed_settings_backend_notify_unapplied (delayed); @@ -403,7 +435,7 @@ g_delayed_settings_backend_finalize (GObject *object) { GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (object); - g_static_mutex_free (&delayed->priv->lock); + g_mutex_clear (&delayed->priv->lock); g_object_unref (delayed->priv->backend); g_tree_unref (delayed->priv->delayed); @@ -420,9 +452,8 @@ g_delayed_settings_backend_class_init (GDelayedSettingsBackendClass *class) GSettingsBackendClass *backend_class = G_SETTINGS_BACKEND_CLASS (class); GObjectClass *object_class = G_OBJECT_CLASS (class); - g_type_class_add_private (class, sizeof (GDelayedSettingsBackendPrivate)); - backend_class->read = g_delayed_settings_backend_read; + backend_class->read_user_value = g_delayed_settings_backend_read_user_value; backend_class->write = g_delayed_settings_backend_write; backend_class->write_tree = g_delayed_settings_backend_write_tree; backend_class->reset = g_delayed_settings_backend_reset; @@ -437,12 +468,9 @@ g_delayed_settings_backend_class_init (GDelayedSettingsBackendClass *class) static void g_delayed_settings_backend_init (GDelayedSettingsBackend *delayed) { - delayed->priv = - G_TYPE_INSTANCE_GET_PRIVATE (delayed, G_TYPE_DELAYED_SETTINGS_BACKEND, - GDelayedSettingsBackendPrivate); - + delayed->priv = g_delayed_settings_backend_get_instance_private (delayed); delayed->priv->delayed = g_settings_backend_create_tree (); - g_static_mutex_init (&delayed->priv->lock); + g_mutex_init (&delayed->priv->lock); } static void @@ -451,10 +479,10 @@ g_delayed_settings_backend_disown (gpointer data, { GDelayedSettingsBackend *delayed = data; - g_static_mutex_lock (&delayed->priv->lock); + g_mutex_lock (&delayed->priv->lock); delayed->priv->owner_context = NULL; delayed->priv->owner = NULL; - g_static_mutex_unlock (&delayed->priv->lock); + g_mutex_unlock (&delayed->priv->lock); } GDelayedSettingsBackend *