From 35b8dac2ca3bf8b2cdd51c8a7a071321f26753ba Mon Sep 17 00:00:00 2001 From: Willian Padovani Germano Date: Tue, 2 May 2006 02:42:08 +0000 Subject: [PATCH] As mentioned in the pydrivers commit, I had to change the order in exit_usiblender() to finalize Python before main library data was freed. This solved a somewhat specific sigsegv with pydrivers, but as Ken Hughes found out (thanks!) caused one with scripts that called Blender.Exit(). Now running scripts (G.main->script) are freed in BPY_end_python() itself (so before the rest of the library data is freed), before Py_Finalize(). Works fine in all my tests so far. The file script.c should become obsolete with this change (I added a comment about it there). If all is indeed fine, it will be removed later. --- source/blender/blenkernel/intern/script.c | 3 +++ source/blender/python/BPY_interface.c | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/source/blender/blenkernel/intern/script.c b/source/blender/blenkernel/intern/script.c index 16b08e37b6c..b99c2c51441 100644 --- a/source/blender/blenkernel/intern/script.c +++ b/source/blender/blenkernel/intern/script.c @@ -54,6 +54,9 @@ #endif */ +/* XXX this function and so also the file should not be needed anymore, + * since we have to force clearing all Python related data before freeing + * Blender's library. Still testing, will decide later (Willian). */ void free_script (Script *script) { if (!script) return; diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index 80c4df81bd4..bffb8f7be8a 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -174,6 +174,8 @@ void BPY_start_python( int argc, char **argv ) /*****************************************************************************/ void BPY_end_python( void ) { + Script *script = NULL; + if( bpy_registryDict ) { Py_DECREF( bpy_registryDict ); bpy_registryDict = NULL; @@ -184,6 +186,13 @@ void BPY_end_python( void ) bpy_pydriver_Dict = NULL; } + /* Freeing all scripts here prevents problems with the order in which + * Python is finalized and G.main is freed in exit_usiblender() */ + for (script = G.main->script.first; script; script = script->id.next) { + BPY_clear_script(script); + free_libblock( &G.main->script, script ); + } + Py_Finalize( ); BPyMenu_RemoveAllEntries( ); /* freeing bpymenu mem */ @@ -912,10 +921,20 @@ void BPY_clear_script( Script * script ) if( !script ) return; + if (!Py_IsInitialized()) { + printf("\nError: trying to free script data after finalizing Python!"); + printf("\nScript name: %s\n", script->id.name+2); + return; + } + Py_XDECREF( ( PyObject * ) script->py_draw ); Py_XDECREF( ( PyObject * ) script->py_event ); Py_XDECREF( ( PyObject * ) script->py_button ); Py_XDECREF( ( PyObject * ) script->py_browsercallback ); + script->py_draw = NULL; + script->py_event = NULL; + script->py_button = NULL; + script->py_browsercallback = NULL; dict = script->py_globaldict;