]> granicus.if.org Git - python/commitdiff
Merged revisions 78382 via svnmerge from
authorThomas Heller <theller@ctypes.org>
Tue, 23 Feb 2010 20:32:43 +0000 (20:32 +0000)
committerThomas Heller <theller@ctypes.org>
Tue, 23 Feb 2010 20:32:43 +0000 (20:32 +0000)
svn+ssh://pythondev@svn.python.org/python/branches/py3k

................
  r78382 | thomas.heller | 2010-02-23 21:25:02 +0100 (Di, 23 Feb 2010) | 11 lines

  Merged revisions 78380 via svnmerge from
  svn+ssh://pythondev@svn.python.org/python/trunk

  ........
    r78380 | thomas.heller | 2010-02-23 21:11:44 +0100 (Di, 23 Feb 2010) | 4 lines

    ctypes CThunkObject was not registered correctly with the cycle
    garbage collector, leading to possible leaks when using callback
    functions.
  ........
................

Lib/ctypes/test/test_callbacks.py
Misc/NEWS
Modules/_ctypes/callbacks.c

index 1bef33f26eb11a21f9e24d21627bae73bc5af619..1466f26ecc9fdfd0e20aae84f256b6939cd3362d 100644 (file)
@@ -118,6 +118,22 @@ class Callbacks(unittest.TestCase):
         prototype = self.functype.__func__(object)
         self.assertRaises(TypeError, prototype, lambda: None)
 
+    def test_issue_7959(self):
+        proto = self.functype.__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.assertEqual(len(live), 0)
+
 try:
     WINFUNCTYPE
 except NameError:
index 5ae0d1aa446b2212862fa726f22ef3d19bfaca6b..329cb4088ffd1e672009a5d6d2b93d560357f7f9 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -86,6 +86,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #7959: ctypes callback functions are now registered correctly
+  with the cylce garbage collector.
+
 - Issue #6666: fix bug in trace.py that applied the list of directories
   to be ignored only to the first file.  Noted by Bogdan Opanchuk.
 
index 328b10f981b38223983c484bef9960fa22e51eb3..9b2cd3fa56db8c549060bbdebb340b208c515311 100644 (file)
@@ -18,7 +18,7 @@ CThunkObject_dealloc(PyObject *_self)
        Py_XDECREF(self->restype);
        if (self->pcl)
                _ctypes_free_closure(self->pcl);
-       PyObject_Del(self);
+       PyObject_GC_Del(self);
 }
 
 static int
@@ -61,7 +61,7 @@ PyTypeObject PyCThunk_Type = {
        0,                                      /* tp_getattro */
        0,                                      /* tp_setattro */
        0,                                      /* tp_as_buffer */
-       Py_TPFLAGS_DEFAULT,                     /* tp_flags */
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,                        /* tp_flags */
        "CThunkObject",                         /* tp_doc */
        CThunkObject_traverse,                  /* tp_traverse */
        CThunkObject_clear,                     /* tp_clear */
@@ -364,7 +364,7 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
        CThunkObject *p;
        int i;
 
-       p = PyObject_NewVar(CThunkObject, &PyCThunk_Type, nArgs);
+       p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs);
        if (p == NULL) {
                PyErr_NoMemory();
                return NULL;
@@ -379,6 +379,7 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
        
        for (i = 0; i < nArgs + 1; ++i)
                p->atypes[i] = NULL;
+       PyObject_GC_Track((PyObject *)p);
        return p;
 }