libnm-glib: ensure object cache is cleared when NM stops (bgo #674473)
authorDan Williams <dcbw@redhat.com>
Mon, 23 Apr 2012 22:07:18 +0000 (17:07 -0500)
committerDan Williams <dcbw@redhat.com>
Mon, 23 Apr 2012 22:10:14 +0000 (17:10 -0500)
Otherwise if a client holds references to the objects (or in the
JavaScript case, uses deferred garbage collection) they'll still
be in the cache when NM restarts, and the old object may have the
same path as some new object, which isn't good.

libnm-glib/nm-client.c
libnm-glib/nm-object-cache.c
libnm-glib/nm-object-cache.h

index bed1b4e..311b1d2 100644 (file)
@@ -1116,6 +1116,11 @@ proxy_name_owner_changed (DBusGProxy *proxy,
                priv->wimax_hw_enabled = FALSE;
                g_free (priv->version);
                priv->version = NULL;
+
+               /* Clear object cache to ensure bad refcounting by clients doesn't
+                * keep objects in the cache.
+                */
+               _nm_object_cache_clear (NM_OBJECT (client));
        } else {
                _nm_object_suppress_property_updates (NM_OBJECT (client), FALSE);
                _nm_object_reload_properties_async (NM_OBJECT (client), updated_properties, client);
index 741f129..2748b1d 100644 (file)
@@ -64,3 +64,28 @@ _nm_object_cache_get (const char *path)
        return object ? g_object_ref (object) : NULL;
 }
 
+void
+_nm_object_cache_clear (NMObject *except)
+{
+       GHashTableIter iter;
+       NMObject *obj;
+       const char *path;
+       char *foo;
+
+       _init_cache ();
+       g_hash_table_iter_init (&iter, cache);
+       while (g_hash_table_iter_next (&iter, (gpointer) &path, (gpointer) &obj)) {
+               if (obj != except) {
+                       /* Remove the callback so that if the object isn't yet released
+                        * by a client, when it does finally get unrefed, it won't trigger
+                        * the cache removal for a new object with the same path as the
+                        * one being released.
+                        */
+                       foo = g_object_steal_data (G_OBJECT (obj), "nm-object-cache-tag");
+                       g_free (foo);
+
+                       g_hash_table_iter_remove (&iter);
+               }
+       }
+}
+
index 8386591..8475213 100644 (file)
@@ -32,6 +32,7 @@ G_BEGIN_DECLS
 /* Returns referenced object from the cache */
 NMObject *_nm_object_cache_get (const char *path);
 void _nm_object_cache_add (NMObject *object);
+void _nm_object_cache_clear (NMObject *except);
 
 G_END_DECLS