From 2ec6bec12610fd0cfed6bc2612c3a9c23815df62 Mon Sep 17 00:00:00 2001 From: Christian Persch Date: Fri, 29 Jul 2005 19:53:46 +0000 Subject: Be careful not to leave a GC scheduled when terminating python. 2005-07-29 Christian Persch * src/ephy-python-extension.c: (impl_detach_tab), (impl_detach_window): * src/ephy-python-loader.c: (ephy_python_loader_finalize): * src/ephy-python.c: (ephy_python_init), (idle_shutdown), (ephy_python_shutdown), (idle_gc), (ephy_python_schedule_gc): * src/ephy-python.h: Be careful not to leave a GC scheduled when terminating python. --- src/ephy-python-extension.c | 5 ++-- src/ephy-python-loader.c | 2 ++ src/ephy-python.c | 73 +++++++++++++++++++++++++++++++++++++++++++++ src/ephy-python.h | 6 +++- 4 files changed, 83 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ephy-python-extension.c b/src/ephy-python-extension.c index 190327f73..a91ce3355 100644 --- a/src/ephy-python-extension.c +++ b/src/ephy-python-extension.c @@ -25,6 +25,7 @@ #include "config.h" #include "ephy-python-extension.h" +#include "ephy-python.h" #include @@ -254,7 +255,7 @@ impl_detach_tab (EphyExtension *extension, { call_python_func (extension, "detach_tab", window, tab); - g_idle_add ((GSourceFunc) PyGC_Collect, NULL); + ephy_python_schedule_gc (); } static void @@ -270,7 +271,7 @@ impl_detach_window (EphyExtension *extension, { call_python_func (extension, "detach_window", window, NULL); - g_idle_add ((GSourceFunc) PyGC_Collect, NULL); + ephy_python_schedule_gc (); } static void diff --git a/src/ephy-python-loader.c b/src/ephy-python-loader.c index d376c39c5..e6c8c5dc5 100644 --- a/src/ephy-python-loader.c +++ b/src/ephy-python-loader.c @@ -93,6 +93,8 @@ ephy_python_loader_finalize (GObject *object) LOG ("EphyPythonLoader finalising"); parent_class->finalize (object); + + ephy_python_shutdown (); } static void diff --git a/src/ephy-python.c b/src/ephy-python.c index 242d19330..01c255879 100644 --- a/src/ephy-python.c +++ b/src/ephy-python.c @@ -26,6 +26,7 @@ #include "config.h" #include "ephy-python.h" +#include "ephy-debug.h" #include #include @@ -35,6 +36,9 @@ void pyepiphany_add_constants (PyObject *module, const gchar *strip_prefix); extern PyMethodDef pyepiphany_functions[]; +static guint idle_gc_handler = 0; +static guint idle_shutdown_handler = 0; + void ephy_python_init (void) { @@ -55,3 +59,72 @@ ephy_python_init (void) pyepiphany_register_classes (d); pyepiphany_add_constants (m, "EPHY_"); } + +static gboolean +idle_shutdown (void) +{ + g_return_val_if_fail (idle_gc_handler == 0, FALSE); + + Py_Finalize (); + + idle_shutdown_handler = 0; + return FALSE; +} + +void +ephy_python_shutdown (void) +{ + g_return_if_fail (idle_shutdown_handler == 0); + + LOG ("EphyPython shutdown with %s GC scheduled", + idle_gc_handler != 0 ? "a" : "no"); + + if (idle_gc_handler != 0) + { + /* Process remaining GCs now */ + while (PyGC_Collect ()) ; + + g_source_remove (idle_gc_handler); + idle_gc_handler = 0; + + /* IMPORTANT! We get here while running PyGC_Collect from idle! + * Don't do Py_Finalize while inside python! + */ + idle_shutdown_handler = g_idle_add ((GSourceFunc) idle_shutdown, NULL); + } + else + { + Py_Finalize(); + } +} + +static gboolean +idle_gc (void) +{ + long value; + + /* LOG ("Running GC from idle"); */ + + /* FIXME what does the return value of PyGC_Collect mean? */ + value = PyGC_Collect (); + + /* LOG ("Idle GC returned %ld", value); */ + + if (value == 0) + { + idle_gc_handler = 0; + } + + return value != 0; +} + +void +ephy_python_schedule_gc (void) +{ + /* LOG ("Scheduling a GC with %s GC already scheduled", idle_gc_handler != 0 ? "a" : "no"); */ + + if (idle_gc_handler == 0) + { + idle_gc_handler = g_idle_add ((GSourceFunc) idle_gc, NULL); + } +} diff --git a/src/ephy-python.h b/src/ephy-python.h index 48b6e3285..d94bb5aeb 100644 --- a/src/ephy-python.h +++ b/src/ephy-python.h @@ -25,7 +25,11 @@ G_BEGIN_DECLS -void ephy_python_init (void); +void ephy_python_init (void); + +void ephy_python_shutdown (void); + +void ephy_python_schedule_gc (void); G_END_DECLS -- cgit v1.2.3