[gnome-builder] sysroot: be safer in use of shared sysroot manager



commit 250d239ff7dc67f770aad8f175f3c803af949d04
Author: Christian Hergert <chergert redhat com>
Date:   Tue Aug 21 13:43:09 2018 -0700

    sysroot: be safer in use of shared sysroot manager
    
    This code was not taking into account the reference drop when a project
    unloads and therefore handing out invalid sysroot instances.

 src/plugins/sysroot/gbp-sysroot-manager.c          |  9 ++++++++-
 src/plugins/sysroot/gbp-sysroot-runtime-provider.c | 20 ++++++++++++++++----
 2 files changed, 24 insertions(+), 5 deletions(-)
---
diff --git a/src/plugins/sysroot/gbp-sysroot-manager.c b/src/plugins/sysroot/gbp-sysroot-manager.c
index 3b5ac9635..0732667a2 100644
--- a/src/plugins/sysroot/gbp-sysroot-manager.c
+++ b/src/plugins/sysroot/gbp-sysroot-manager.c
@@ -120,8 +120,15 @@ gbp_sysroot_manager_get_default (void)
 {
   static GbpSysrootManager *instance;
 
+  /* TODO: This needs to be attached to the IdeContext somehow, as this is
+   *       not ideal when two contexts are loaded and sharing occurs.
+   */
+
   if (instance == NULL)
-    instance = g_object_new (GBP_TYPE_SYSROOT_MANAGER, NULL);
+    {
+      instance = g_object_new (GBP_TYPE_SYSROOT_MANAGER, NULL);
+      g_object_add_weak_pointer (G_OBJECT (instance), (gpointer *)&instance);
+    }
 
   return instance;
 }
diff --git a/src/plugins/sysroot/gbp-sysroot-runtime-provider.c 
b/src/plugins/sysroot/gbp-sysroot-runtime-provider.c
index 5c1244715..f89ff5992 100644
--- a/src/plugins/sysroot/gbp-sysroot-runtime-provider.c
+++ b/src/plugins/sysroot/gbp-sysroot-runtime-provider.c
@@ -82,6 +82,8 @@ sysroot_runtime_provider_target_changed (GbpSysrootRuntimeProvider
                                          GbpSysrootManagerTargetModificationType  mod_type,
                                          gpointer                                 user_data)
 {
+  g_assert (GBP_IS_SYSROOT_RUNTIME_PROVIDER (self));
+
   if (mod_type == GBP_SYSROOT_MANAGER_TARGET_CREATED)
     sysroot_runtime_provider_add_target (self, target);
   else if (mod_type == GBP_SYSROOT_MANAGER_TARGET_REMOVED)
@@ -125,10 +127,14 @@ gbp_sysroot_runtime_provider_load (IdeRuntimeProvider *provider,
       sysroot_runtime_provider_add_target (self, sysroots[i]);
     }
 
-  g_signal_connect_swapped (sysroot_manager,
-                            "target-changed",
-                            G_CALLBACK (sysroot_runtime_provider_target_changed),
-                            self);
+  /* Hold extra ref during plugin load */
+  g_object_ref (sysroot_manager);
+
+  g_signal_connect_object (sysroot_manager,
+                           "target-changed",
+                           G_CALLBACK (sysroot_runtime_provider_target_changed),
+                           self,
+                           G_CONNECT_SWAPPED);
 
   IDE_EXIT;
 }
@@ -146,6 +152,12 @@ gbp_sysroot_runtime_provider_unload (IdeRuntimeProvider *provider,
   g_assert (IDE_IS_RUNTIME_MANAGER (manager));
 
   sysroot_manager = gbp_sysroot_manager_get_default ();
+
+  /* Drop shared instance if last instance usage */
+  if (G_OBJECT (sysroot_manager)->ref_count == 2)
+    g_object_unref (sysroot_manager);
+
+  /* Drop our ref from project load */
   g_object_unref (sysroot_manager);
 
   if (self->runtimes != NULL)


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