[libpeas] Prevent and warn when trying to enable multiple loaders



commit 3bebe412722d5dff4bc908aee3b6345406ba7c60
Author: Garrett Regier <garrettregier gmail com>
Date:   Thu May 29 18:40:33 2014 -0700

    Prevent and warn when trying to enable multiple loaders
    
    Using multiple plugin loaders will cause memory leaks due to
    both the python 2/3 and seed binding using toggle refs. Also
    mixing python version will never work.

 libpeas/peas-engine.c        |   34 +++++++++++++++++++++++++++++++---
 peas-demo/peas-demo.c        |    2 ++
 tests/libpeas/extension-py.c |    3 +++
 3 files changed, 36 insertions(+), 3 deletions(-)
---
diff --git a/libpeas/peas-engine.c b/libpeas/peas-engine.c
index 9d66f08..608dbfa 100644
--- a/libpeas/peas-engine.c
+++ b/libpeas/peas-engine.c
@@ -712,14 +712,20 @@ get_plugin_loader (PeasEngine     *engine,
  * @loader_id: The id of the loader to enable.
  *
  * Enable a loader, enables a loader for plugins.
- * The C plugin loader is always enabled.
+ * The C plugin loader is always enabled. The other plugin
+ * loaders are: python, python3 and seed.
  *
- * For instance, the following code will enable python plugin
- * from being loaded:
+ * For instance, the following code will enable python plugins
+ * to be loaded:
  * |[
  * peas_engine_enable_loader (engine, "python");
  * ]|
  *
+ * Due to the use of toggle references in the python, python3 and
+ * seed bindings only one of them should be enabled. Otherwise vast
+ * memory leaks are to be expected and as such it is an error to
+ * enable more than one of them.
+ *
  * Note: plugin loaders are shared across #PeasEngines so enabling
  *       a loader on one #PeasEngine will enable it on all #PeasEngines.
  **/
@@ -733,6 +739,28 @@ peas_engine_enable_loader (PeasEngine  *engine,
   if (g_hash_table_lookup_extended (loaders, loader_id, NULL, NULL))
     return;
 
+  /* The demo and some tests need to load multiple loaders */
+  if (g_getenv ("PEAS_ALLOW_ALL_LOADERS") == NULL)
+    {
+      static const gchar *plugin_loader_ids[] = {"python", "python3", "seed"};
+      gint i;
+
+      for (i = 0; i < G_N_ELEMENTS (plugin_loader_ids); ++i)
+        {
+          if (g_ascii_strcasecmp (loader_id, plugin_loader_ids[i]) == 0)
+            continue;
+
+          if (g_hash_table_lookup_extended (loaders, plugin_loader_ids[i],
+                                            NULL, NULL))
+            {
+              g_warning ("Cannot enable plugin loader '%s' as the "
+                         "'%s' plugin loader has already been enabled.",
+                         loader_id, plugin_loader_ids[i]);
+              return;
+            }
+        }
+    }
+
   /* We do not load the plugin loader immediately and instead
    * load it in get_plugin_loader() so that it is loaded lazily.
    */
diff --git a/peas-demo/peas-demo.c b/peas-demo/peas-demo.c
index 22fb41e..c0c0bca 100644
--- a/peas-demo/peas-demo.c
+++ b/peas-demo/peas-demo.c
@@ -125,6 +125,8 @@ main (int    argc,
   peas_engine_add_search_path (engine, plugin_dir, plugin_dir);
   g_free (plugin_dir);
 
+  /* We don't care about leaking memory */
+  g_setenv ("PEAS_ALLOW_ALL_LOADERS", "1", TRUE);
   peas_engine_enable_loader (engine, "python3");
   peas_engine_enable_loader (engine, "seed");
 
diff --git a/tests/libpeas/extension-py.c b/tests/libpeas/extension-py.c
index b50eeb9..5cb7788 100644
--- a/tests/libpeas/extension-py.c
+++ b/tests/libpeas/extension-py.c
@@ -180,6 +180,9 @@ test_extension_py_mixed_python_subprocess (void)
   testing_util_push_log_hook ("*Could not find loader '"
                               ALT_PY_LOADER_STR "'*");
 
+  /* Required when loading multiple loaders */
+  g_setenv ("PEAS_ALLOW_ALL_LOADERS", "1", TRUE);
+
   engine = testing_engine_new ();
   peas_engine_enable_loader (engine, ALT_PY_LOADER_STR);
 


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