[Python] Fix memory leak.
SWIG python objects were being freed after the corresponding SWIG module information was destroyed in Python 3, causing leaks when as a result the object destructor could not be invoked. To prevent this misordering, SWIG python objects now obtain a reference to the Python capsule wrapping the module information, so that the module information is correctly destroyed after all SWIG python objects have been freed (and corresponding destructors invoked). Fixes #2154 Fixes #2208
This commit is contained in:
parent
f822bbf382
commit
e5996be10c
2 changed files with 22 additions and 2 deletions
|
|
@ -154,6 +154,17 @@ Version 4.1.0 (in progress)
|
|||
things like `%std::vector<std::string>` now give an error rather
|
||||
than being quietly ignored.
|
||||
|
||||
2022-02-11: adr26
|
||||
[Python] #2154 Fix memory leak.
|
||||
|
||||
SWIG python objects were being freed after the corresponding SWIG
|
||||
module information was destroyed in Python 3, causing leaks when as
|
||||
a result the object destructor could not be invoked. To prevent this
|
||||
misordering, SWIG python objects now obtain a reference to the
|
||||
Python capsule wrapping the module information, so that the module
|
||||
information is correctly destroyed after all SWIG python objects
|
||||
have been freed (and corresponding destructors invoked).
|
||||
|
||||
2022-02-10: olly
|
||||
[Tcl] https://sourceforge.net/p/swig/bugs/1207/
|
||||
https://sourceforge.net/p/swig/bugs/1213/
|
||||
|
|
|
|||
|
|
@ -719,6 +719,8 @@ SwigPyObject_Check(PyObject *op) {
|
|||
SWIGRUNTIME PyObject *
|
||||
SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
|
||||
|
||||
static PyObject* Swig_Capsule_global = NULL;
|
||||
|
||||
SWIGRUNTIME void
|
||||
SwigPyObject_dealloc(PyObject *v)
|
||||
{
|
||||
|
|
@ -769,7 +771,8 @@ SwigPyObject_dealloc(PyObject *v)
|
|||
printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Py_XDECREF(Swig_Capsule_global);
|
||||
}
|
||||
Py_XDECREF(next);
|
||||
#ifdef SWIGPYTHON_BUILTIN
|
||||
Py_XDECREF(sobj->dict);
|
||||
|
|
@ -994,6 +997,9 @@ SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
|
|||
#ifdef SWIGPYTHON_BUILTIN
|
||||
sobj->dict = 0;
|
||||
#endif
|
||||
if (own == SWIG_POINTER_OWN) {
|
||||
Py_XINCREF(Swig_Capsule_global);
|
||||
}
|
||||
}
|
||||
return (PyObject *)sobj;
|
||||
}
|
||||
|
|
@ -1663,6 +1669,7 @@ SWIG_Python_DestroyModule(PyObject *obj)
|
|||
Swig_Globals_global = NULL;
|
||||
Py_DECREF(SWIG_Python_TypeCache());
|
||||
Swig_TypeCache_global = NULL;
|
||||
Swig_Capsule_global = NULL;
|
||||
}
|
||||
|
||||
SWIGRUNTIME void
|
||||
|
|
@ -1676,7 +1683,9 @@ SWIG_Python_SetModule(swig_module_info *swig_module) {
|
|||
#endif
|
||||
PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule);
|
||||
if (pointer && module) {
|
||||
if (PyModule_AddObject(module, "type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer) != 0) {
|
||||
if (PyModule_AddObject(module, "type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer) == 0) {
|
||||
Swig_Capsule_global = pointer;
|
||||
} else {
|
||||
Py_DECREF(pointer);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue