Fix T82675: Crash on exit when Blender is built as a Python module

This commit is contained in:
2021-01-28 14:38:08 +11:00
parent 198980693b
commit 87d3f4aff3
3 changed files with 16 additions and 2 deletions

View File

@@ -442,6 +442,13 @@ void BPY_python_start(bContext *C, int argc, const char **argv)
py_tstate = PyGILState_GetThisThreadState(); py_tstate = PyGILState_GetThisThreadState();
PyEval_ReleaseThread(py_tstate); PyEval_ReleaseThread(py_tstate);
#endif #endif
#ifdef WITH_PYTHON_MODULE
/* Disable all add-ons at exit, not essential, it just avoids resource leaks, see T71362. */
BPY_run_string_eval(C,
(const char *[]){"atexit", "addon_utils", NULL},
"atexit.register(addon_utils.disable_all)");
#endif
} }
void BPY_python_end(void) void BPY_python_end(void)

View File

@@ -168,6 +168,9 @@ if(WITH_PYTHON)
../python ../python
) )
add_definitions(-DWITH_PYTHON) add_definitions(-DWITH_PYTHON)
if(WITH_PYTHON_MODULE)
add_definitions(-DWITH_PYTHON_MODULE)
endif()
endif() endif()
if(WITH_BUILDINFO) if(WITH_BUILDINFO)

View File

@@ -523,11 +523,15 @@ void WM_exit_ex(bContext *C, const bool do_python)
} }
} }
#ifdef WITH_PYTHON #if defined(WITH_PYTHON) && !defined(WITH_PYTHON_MODULE)
/* Without this, we there isn't a good way to manage false-positive resource leaks /* Without this, we there isn't a good way to manage false-positive resource leaks
* where a #PyObject references memory allocated with guarded-alloc, T71362. * where a #PyObject references memory allocated with guarded-alloc, T71362.
* *
* This allows add-ons to free resources when unregistered (which is good practice anyway). */ * This allows add-ons to free resources when unregistered (which is good practice anyway).
*
* Don't run this code when built as a Python module as this runs when Python is in the
* process of shutting down, where running a snippet like this will crash, see T82675.
* Instead use the `atexit` module, installed by #BPY_python_start */
BPY_run_string_eval(C, (const char *[]){"addon_utils", NULL}, "addon_utils.disable_all()"); BPY_run_string_eval(C, (const char *[]){"addon_utils", NULL}, "addon_utils.disable_all()");
#endif #endif