[gnome-builder] plugins: release plugins during IdeExtensionSetAdapater.dispose



commit 4d8ce5ad0f6455ed8af531079613176133174d0f
Author: Christian Hergert <chergert redhat com>
Date:   Sun Aug 20 12:52:42 2017 -0700

    plugins: release plugins during IdeExtensionSetAdapater.dispose
    
    We were leaking extensions when we were disposed without first NULL'ing
    out the matching extensions. This ensures that we cleanup any future
    extensions in the dispose phase.
    
    To avoid breaking expectations about having a valid self->extensions
    hashtable, we replace a dummy hashtable in case the object tries to
    outlive the GObjectClass.dispose call.

 libide/plugins/ide-extension-set-adapter.c |   33 ++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)
---
diff --git a/libide/plugins/ide-extension-set-adapter.c b/libide/plugins/ide-extension-set-adapter.c
index 247a8b0..3490020 100644
--- a/libide/plugins/ide-extension-set-adapter.c
+++ b/libide/plugins/ide-extension-set-adapter.c
@@ -264,6 +264,38 @@ ide_extension_set_adapter_set_interface_type (IdeExtensionSetAdapter *self,
 }
 
 static void
+ide_extension_set_adapter_dispose (GObject *object)
+{
+  IdeExtensionSetAdapter *self = (IdeExtensionSetAdapter *)object;
+  g_autoptr(GHashTable) extensions = NULL;
+  GHashTableIter iter;
+  gpointer key;
+  gpointer value;
+
+  g_assert (IDE_IS_EXTENSION_SET_ADAPTER (self));
+
+  /*
+   * Steal the extensions so we can be re-entrant safe and not break
+   * any assumptions about extensions being a real pointer.
+   */
+  extensions = g_steal_pointer (&self->extensions);
+  self->extensions = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
+
+  g_hash_table_iter_init (&iter, extensions);
+
+  while (g_hash_table_iter_next (&iter, &key, &value))
+    {
+      PeasPluginInfo *plugin_info = key;
+      PeasExtension *exten = value;
+
+      remove_extension (self, plugin_info, exten);
+      g_hash_table_iter_remove (&iter);
+    }
+
+  G_OBJECT_CLASS (ide_extension_set_adapter_parent_class)->dispose (object);
+}
+
+static void
 ide_extension_set_adapter_finalize (GObject *object)
 {
   IdeExtensionSetAdapter *self = (IdeExtensionSetAdapter *)object;
@@ -355,6 +387,7 @@ ide_extension_set_adapter_class_init (IdeExtensionSetAdapterClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  object_class->dispose = ide_extension_set_adapter_dispose;
   object_class->finalize = ide_extension_set_adapter_finalize;
   object_class->get_property = ide_extension_set_adapter_get_property;
   object_class->set_property = ide_extension_set_adapter_set_property;


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