Kaydet (Commit) 92bd059c authored tarafından Thomas Heller's avatar Thomas Heller

ctypes CThunkObject was not registered correctly with the cycle

garbage collector, leading to possible leaks when using callback
functions.
üst 429a74a1
...@@ -118,6 +118,22 @@ class Callbacks(unittest.TestCase): ...@@ -118,6 +118,22 @@ class Callbacks(unittest.TestCase):
prototype = self.functype.im_func(object) prototype = self.functype.im_func(object)
self.assertRaises(TypeError, prototype, lambda: None) self.assertRaises(TypeError, prototype, lambda: None)
def test_issue_7959(self):
proto = self.functype.im_func(None)
class X(object):
def func(self): pass
def __init__(self):
self.v = proto(self.func)
import gc
for i in range(32):
X()
gc.collect()
live = [x for x in gc.get_objects()
if isinstance(x, X)]
self.failUnlessEqual(len(live), 0)
try: try:
WINFUNCTYPE WINFUNCTYPE
except NameError: except NameError:
......
...@@ -27,6 +27,9 @@ Core and Builtins ...@@ -27,6 +27,9 @@ Core and Builtins
Library Library
------- -------
- Issue #7959: ctypes callback functions are now registered correctly
with the cylce garbage collector.
- Issue #7970: email.Generator.flatten now correctly flattens message/rfc822 - Issue #7970: email.Generator.flatten now correctly flattens message/rfc822
messages parsed by email.Parser.HeaderParser. messages parsed by email.Parser.HeaderParser.
......
...@@ -23,7 +23,7 @@ CThunkObject_dealloc(PyObject *_self) ...@@ -23,7 +23,7 @@ CThunkObject_dealloc(PyObject *_self)
Py_XDECREF(self->restype); Py_XDECREF(self->restype);
if (self->pcl) if (self->pcl)
_ctypes_free_closure(self->pcl); _ctypes_free_closure(self->pcl);
PyObject_Del(self); PyObject_GC_Del(self);
} }
static int static int
...@@ -66,7 +66,7 @@ PyTypeObject PyCThunk_Type = { ...@@ -66,7 +66,7 @@ PyTypeObject PyCThunk_Type = {
0, /* tp_getattro */ 0, /* tp_getattro */
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
"CThunkObject", /* tp_doc */ "CThunkObject", /* tp_doc */
CThunkObject_traverse, /* tp_traverse */ CThunkObject_traverse, /* tp_traverse */
CThunkObject_clear, /* tp_clear */ CThunkObject_clear, /* tp_clear */
...@@ -385,7 +385,7 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nArgs) ...@@ -385,7 +385,7 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
CThunkObject *p; CThunkObject *p;
int i; int i;
p = PyObject_NewVar(CThunkObject, &PyCThunk_Type, nArgs); p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs);
if (p == NULL) { if (p == NULL) {
PyErr_NoMemory(); PyErr_NoMemory();
return NULL; return NULL;
...@@ -400,6 +400,7 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nArgs) ...@@ -400,6 +400,7 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
for (i = 0; i < nArgs + 1; ++i) for (i = 0; i < nArgs + 1; ++i)
p->atypes[i] = NULL; p->atypes[i] = NULL;
PyObject_GC_Track((PyObject *)p);
return p; return p;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment