X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgdelayedsettingsbackend.c;h=22a42ebdaeed409c28f7e9e4e7f1835a69ca42a3;hb=9da85c7262325478e8730ae9f3e76bd0528a9a8c;hp=fd166a1ccf1a41a103f274ae340249f46740c5a2;hpb=aed440815ec5c87f2439d723b60b8255578afdff;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gdelayedsettingsbackend.c b/gio/gdelayedsettingsbackend.c index fd166a1..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,24 +65,10 @@ 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) - { - if (g_settings_backend_get_active_context () != target_context) - { - GSource *source; - - source = g_idle_source_new (); - g_source_set_priority (source, G_PRIORITY_DEFAULT); - g_source_set_callback (source, invoke_notify_unapplied, - target, g_object_unref); - g_source_attach (source, target_context); - g_source_unref (source); - } - else - invoke_notify_unapplied (target); - } + g_main_context_invoke (target_context, invoke_notify_unapplied, target); } @@ -99,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 */ @@ -108,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) @@ -118,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, @@ -127,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); @@ -151,18 +161,18 @@ add_to_tree (gpointer key, } static gboolean -g_delayed_settings_backend_write_keys (GSettingsBackend *backend, +g_delayed_settings_backend_write_tree (GSettingsBackend *backend, GTree *tree, gpointer origin_tag) { 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); @@ -189,24 +199,16 @@ 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); } static void -g_delayed_settings_backend_reset_path (GSettingsBackend *backend, - const gchar *path, - gpointer origin_tag) -{ - /* deal with this... */ -} - -static void g_delayed_settings_backend_subscribe (GSettingsBackend *backend, const char *name) { @@ -251,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_keys (delayed->priv->backend, + 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), @@ -275,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); @@ -288,8 +290,8 @@ g_delayed_settings_backend_revert (GDelayedSettingsBackend *delayed) /* change notification */ static void -delayed_backend_changed (GSettingsBackend *backend, - GObject *target, +delayed_backend_changed (GObject *target, + GSettingsBackend *backend, const gchar *key, gpointer origin_tag) { @@ -301,11 +303,11 @@ delayed_backend_changed (GSettingsBackend *backend, } static void -delayed_backend_keys_changed (GSettingsBackend *backend, - GObject *target, +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); @@ -315,8 +317,8 @@ delayed_backend_keys_changed (GSettingsBackend *backend, } static void -delayed_backend_path_changed (GSettingsBackend *backend, - GObject *target, +delayed_backend_path_changed (GObject *target, + GSettingsBackend *backend, const gchar *path, gpointer origin_tag) { @@ -328,20 +330,25 @@ delayed_backend_path_changed (GSettingsBackend *backend, } static void -delayed_backend_writable_changed (GSettingsBackend *backend, - GObject *target, +delayed_backend_writable_changed (GObject *target, + GSettingsBackend *backend, const gchar *key) { 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); @@ -349,7 +356,7 @@ delayed_backend_writable_changed (GSettingsBackend *backend, 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); @@ -380,15 +387,15 @@ check_prefix (gpointer key, } static void -delayed_backend_path_writable_changed (GSettingsBackend *backend, - GObject *target, +delayed_backend_path_writable_changed (GObject *target, + GSettingsBackend *backend, const gchar *path) { GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (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); @@ -400,9 +407,12 @@ delayed_backend_path_writable_changed (GSettingsBackend *backend, /* 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]); @@ -411,7 +421,7 @@ delayed_backend_path_writable_changed (GSettingsBackend *backend, 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); @@ -425,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); @@ -442,13 +452,11 @@ 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_keys = g_delayed_settings_backend_write_keys; + backend_class->write_tree = g_delayed_settings_backend_write_tree; backend_class->reset = g_delayed_settings_backend_reset; - backend_class->reset_path = g_delayed_settings_backend_reset_path; backend_class->get_writable = g_delayed_settings_backend_get_writable; backend_class->subscribe = g_delayed_settings_backend_subscribe; backend_class->unsubscribe = g_delayed_settings_backend_unsubscribe; @@ -460,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 @@ -474,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 * @@ -485,6 +490,13 @@ g_delayed_settings_backend_new (GSettingsBackend *backend, gpointer owner, GMainContext *owner_context) { + static GSettingsListenerVTable vtable = { + delayed_backend_changed, + delayed_backend_path_changed, + delayed_backend_keys_changed, + delayed_backend_writable_changed, + delayed_backend_path_writable_changed + }; GDelayedSettingsBackend *delayed; delayed = g_object_new (G_TYPE_DELAYED_SETTINGS_BACKEND, NULL); @@ -494,12 +506,8 @@ g_delayed_settings_backend_new (GSettingsBackend *backend, g_object_weak_ref (owner, g_delayed_settings_backend_disown, delayed); - g_settings_backend_watch (delayed->priv->backend, G_OBJECT (delayed), NULL, - delayed_backend_changed, - delayed_backend_path_changed, - delayed_backend_keys_changed, - delayed_backend_writable_changed, - delayed_backend_path_writable_changed); + g_settings_backend_watch (delayed->priv->backend, + &vtable, G_OBJECT (delayed), NULL); return delayed; }