[Xfce4-commits] <xfconf:master> Wait for pending calls in the cache.

Nick Schermer noreply at xfce.org
Tue Dec 29 20:40:01 CET 2009


Updating branch refs/heads/master
         to d683d6fcaa8784a4c5df487496d0d774e2c10722 (commit)
       from 6b3dc965b9d5b20d9dd97f2b79cd99d95324546f (commit)

commit d683d6fcaa8784a4c5df487496d0d774e2c10722
Author: Nick Schermer <nick at xfce.org>
Date:   Tue Dec 29 20:33:51 2009 +0100

    Wait for pending calls in the cache.
    
    Brian already added a FIXME with the question if we should
    wait for pending calls to finish before freeing the items.
    Well the question is yes, because the get-tests failed on my
    system because the channel was closed in the set-tests before
    dbus replied and thus nothing was stored in the test-channel.
    
    So wait for pending calls in finalize and skip the normal reply
    handler by setting the hash table in the cache to NULL.

 xfconf/xfconf-cache.c |   52 ++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/xfconf/xfconf-cache.c b/xfconf/xfconf-cache.c
index b6bffe7..fefaba1 100644
--- a/xfconf/xfconf-cache.c
+++ b/xfconf/xfconf-cache.c
@@ -131,11 +131,10 @@ xfconf_cache_old_item_free(XfconfCacheOldItem *old_item)
 {
     g_return_if_fail(old_item);
 
-    if(old_item->call) {
-        /* FIXME: maybe should force them to complete */
-        DBusGProxy *proxy = _xfconf_get_dbus_g_proxy();
-        dbus_g_proxy_cancel_call(proxy, old_item->call);
-    }
+    /* debug check to make sure the call is properly handled before
+     * freeing the item. it should either been canceled to we wait for
+     * it to finish */
+    g_return_if_fail(!old_item->call);
 
     g_free(old_item->property);
 
@@ -145,6 +144,29 @@ xfconf_cache_old_item_free(XfconfCacheOldItem *old_item)
     g_slice_free(XfconfCacheOldItem, old_item);
 }
 
+static gboolean
+xfconf_cache_old_item_end_call(gpointer key,
+                               gpointer value,
+                               gpointer user_data)
+{
+    const gchar *channel_name = user_data;
+    DBusGProxy *proxy = _xfconf_get_dbus_g_proxy();
+    GError *error = NULL;
+    XfconfCacheOldItem *old_item = value;
+
+    g_return_val_if_fail(old_item->call, TRUE);
+
+    if(!dbus_g_proxy_end_call(proxy, old_item->call, &error, G_TYPE_INVALID)) {
+       g_warning("Failed to set property \"%s::%s\": %s",
+                  channel_name, old_item->property, error->message);
+        g_error_free(error);
+    }
+
+    old_item->call = NULL;
+
+    return TRUE;
+}
+
 
 /************************* XfconfCache ********************/
 
@@ -367,6 +389,7 @@ xfconf_cache_finalize(GObject *obj)
 {
     XfconfCache *cache = XFCONF_CACHE(obj);
     DBusGProxy *proxy = _xfconf_get_dbus_g_proxy();
+    GHashTable *pending_calls;
 
     dbus_g_proxy_disconnect_signal(proxy, "PropertyChanged",
                                    G_CALLBACK(xfconf_cache_property_changed),
@@ -376,10 +399,17 @@ xfconf_cache_finalize(GObject *obj)
                                    G_CALLBACK(xfconf_cache_property_removed),
                                    cache);
 
+    /* finish pending calls (without emitting signals, therefore we set
+     * the hash table in the cache to %NULL) */
+    pending_calls = cache->pending_calls;
+    cache->pending_calls = NULL;
+    g_hash_table_foreach_remove(pending_calls, xfconf_cache_old_item_end_call,
+                                cache->channel_name);
+    g_hash_table_unref(pending_calls);
+
     g_free(cache->channel_name);
 
     g_tree_destroy(cache->properties);
-    g_hash_table_destroy(cache->pending_calls);
     g_hash_table_destroy(cache->old_properties);
 
     g_static_mutex_free(&cache->cache_lock);
@@ -452,6 +482,9 @@ xfconf_cache_set_property_reply_handler(DBusGProxy *proxy,
     XfconfCacheItem *item;
     GError *error = NULL;
 
+    if(!cache->pending_calls)
+        return;
+
     xfconf_cache_mutex_lock(&cache->cache_lock);
 
     old_item = g_hash_table_lookup(cache->pending_calls, call);
@@ -469,9 +502,7 @@ xfconf_cache_set_property_reply_handler(DBusGProxy *proxy,
     g_hash_table_remove(cache->old_properties, old_item->property);
     /* don't destroy old_item yet */
     g_hash_table_steal(cache->pending_calls, old_item->call);
-    
-    /* NULL this out so we don't try to cancel it in the remove function */
-    old_item->call = NULL;
+
     if(!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_INVALID)) {
         /* failed to set the value.  reset it to the old value and send
          * a prop changed signal to the channel */
@@ -497,6 +528,9 @@ xfconf_cache_set_property_reply_handler(DBusGProxy *proxy,
         xfconf_cache_mutex_lock(&cache->cache_lock);
     }
 
+    /* we handled the call, so set it to %NULL */
+    old_item->call = NULL;
+
     if(old_item)
         xfconf_cache_old_item_free(old_item);
 out:



More information about the Xfce4-commits mailing list