[libpeas] Added peas_engine_shutdown()
- From: Garrett Regier <gregier src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libpeas] Added peas_engine_shutdown()
- Date: Wed, 9 Feb 2011 08:40:01 +0000 (UTC)
commit 71bc92d78f70f83e52794a63da5144d3b0efe920
Author: Garrett Regier <alias301 gmail com>
Date: Sun Feb 6 03:45:44 2011 -0800
Added peas_engine_shutdown()
It frees the memory the memory that is shared
by PeasEngines.
libpeas/peas-engine.c | 49 +++++++++++++++++++++++++++++++++++
libpeas/peas-engine.h | 1 +
peas-demo/peas-demo.c | 6 +++-
tests/libpeas-gtk/testing/testing.c | 2 +
tests/libpeas/engine.c | 45 ++++++++++++++++++++++++++++++++
tests/libpeas/testing/testing.c | 2 +
6 files changed, 103 insertions(+), 2 deletions(-)
---
diff --git a/libpeas/peas-engine.c b/libpeas/peas-engine.c
index 99d150f..2258563 100644
--- a/libpeas/peas-engine.c
+++ b/libpeas/peas-engine.c
@@ -344,6 +344,13 @@ peas_engine_constructor (GType type,
return NULL;
}
+ if (shutdown)
+ {
+ g_warning ("libpeas cannot create a plugin engine "
+ "as it has been shutdown.");
+ return NULL;
+ }
+
if (default_engine != NULL)
return g_object_ref (G_OBJECT (default_engine));
@@ -1168,3 +1175,45 @@ peas_engine_get_default (void)
return default_engine;
}
+
+static void
+destroy_loaders (void)
+{
+ g_hash_table_destroy (loaders);
+ loaders = NULL;
+}
+
+/**
+ * peas_engine_shutdown:
+ *
+ * Frees memory shared by PeasEngines.
+ * No libpeas API should be called after calling this.
+ */
+void
+peas_engine_shutdown (void)
+{
+ if (shutdown)
+ return;
+
+ shutdown = TRUE;
+
+ if (default_engine != NULL)
+ {
+ /* Add a weak ref that will destroy the loaders hashtable,
+ * this way if the engine is still around it won't segfault
+ */
+ g_object_weak_ref (G_OBJECT (default_engine),
+ (GWeakNotify) destroy_loaders, NULL);
+
+ g_object_unref (default_engine);
+
+ /* The weak-ref should set it to NULL */
+ if (default_engine != NULL)
+ {
+ default_engine = NULL;
+
+ g_warning ("libpeas failed to shutdown, "
+ "the plugin engine was not freed.");
+ }
+ }
+}
diff --git a/libpeas/peas-engine.h b/libpeas/peas-engine.h
index df56800..27370ba 100644
--- a/libpeas/peas-engine.h
+++ b/libpeas/peas-engine.h
@@ -69,6 +69,7 @@ struct _PeasEngineClass {
GType peas_engine_get_type (void) G_GNUC_CONST;
PeasEngine *peas_engine_get_default (void);
+void peas_engine_shutdown (void);
void peas_engine_add_search_path (PeasEngine *engine,
const gchar *module_dir,
diff --git a/peas-demo/peas-demo.c b/peas-demo/peas-demo.c
index 6420b07..3c11753 100644
--- a/peas-demo/peas-demo.c
+++ b/peas-demo/peas-demo.c
@@ -59,7 +59,7 @@ create_main_window (void)
GtkWidget *button;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+ g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 6);
gtk_window_set_title (GTK_WINDOW (window), "Peas Demo");
@@ -138,7 +138,9 @@ main (int argc,
gtk_main ();
- g_object_unref (engine);
+ gtk_widget_destroy (main_window);
+
+ peas_engine_shutdown ();
return 0;
}
diff --git a/tests/libpeas-gtk/testing/testing.c b/tests/libpeas-gtk/testing/testing.c
index a2a850d..549fadc 100644
--- a/tests/libpeas-gtk/testing/testing.c
+++ b/tests/libpeas-gtk/testing/testing.c
@@ -108,6 +108,8 @@ testing_engine_new (void)
g_irepository_require (g_irepository_get_default (), "PeasGtk", "1.0", 0, &error);
g_assert_no_error (error);
+ g_atexit (peas_engine_shutdown);
+
initialized = TRUE;
}
diff --git a/tests/libpeas/engine.c b/tests/libpeas/engine.c
index 07a526d..2751c2a 100644
--- a/tests/libpeas/engine.c
+++ b/tests/libpeas/engine.c
@@ -295,6 +295,48 @@ test_engine_disable_loader (PeasEngine *engine)
g_test_trap_assert_stderr ("*Loader 'C' cannot be disabled*");
}
+static void
+test_engine_shutdown (PeasEngine *engine)
+{
+ PeasPluginInfo *info;
+
+ /* Ref the engine to cause the shutdown to fail */
+ g_object_ref (engine);
+
+ /* libpeas fails to shutdown because the engine still has a ref */
+ if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
+ {
+ peas_engine_shutdown ();
+ exit (0);
+ }
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("*libpeas failed to shutdown*"
+ "*plugin engine was not freed*");
+
+ /* Make sure that if an engine is around
+ * after shutdown the engine does not segfault.
+ */
+ info = peas_engine_get_plugin_info (engine, "loadable");
+ g_assert (peas_engine_load_plugin (engine, info));
+
+ /* Free our extra ref and then the engine */
+ g_object_unref (engine);
+ testing_engine_free (engine);
+
+ /* Should be able to shutdown multiple times */
+ peas_engine_shutdown ();
+
+ /* Cannot get the default as libpeas has been shutdown */
+ if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
+ {
+ peas_engine_get_default ();
+ exit (0);
+ }
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("*libpeas cannot create a plugin "
+ "engine as it has been shutdown*");
+}
+
int
main (int argc,
char **argv)
@@ -326,6 +368,9 @@ main (int argc,
TEST ("invalid-loader", invalid_loader);
TEST ("disable-loader", disable_loader);
+ /* MUST be last */
+ TEST ("shutdown", shutdown);
+
#undef TEST
return g_test_run ();
diff --git a/tests/libpeas/testing/testing.c b/tests/libpeas/testing/testing.c
index fbccbe0..c29e122 100644
--- a/tests/libpeas/testing/testing.c
+++ b/tests/libpeas/testing/testing.c
@@ -116,6 +116,8 @@ testing_engine_new (void)
"Introspection", "1.0", 0, &error);
g_assert_no_error (error);
+ g_atexit (peas_engine_shutdown);
+
initialized = TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]