Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r2276:a38f64ce5c4f
Date: 2015-09-26 08:51 +0200
http://bitbucket.org/cffi/cffi/changeset/a38f64ce5c4f/

Log:    Issue #223

        Workaround: CPython 3.4 broke compatibility by adding tp_finalize,
        which in this case must be implemented too to avoid ordering issues
        at shutdown. (In <= 3.3 it works fine.)

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -1653,14 +1653,13 @@
 static void _my_PyErr_WriteUnraisable(char *objdescr, PyObject *obj,
                                       char *extra_error_line);
 
-static void cdatagcp_dealloc(CDataObject_gcp *cd)
-{
-    PyObject *result;
-    PyObject *destructor = cd->destructor;
-    PyObject *origobj = cd->origobj;
-    cdata_dealloc((CDataObject *)cd);
+
+static void gcp_finalize(PyObject *destructor, PyObject *origobj)
+{
+    /* NOTE: this decrements the reference count of the two arguments */
 
     if (destructor != NULL) {
+        PyObject *result;
         PyObject *error_type, *error_value, *error_traceback;
 
         /* Save the current exception */
@@ -1679,7 +1678,27 @@
         /* Restore the saved exception */
         PyErr_Restore(error_type, error_value, error_traceback);
     }
-    Py_DECREF(origobj);
+    Py_XDECREF(origobj);
+}
+
+#ifdef Py_TPFLAGS_HAVE_FINALIZE     /* CPython >= 3.4 */
+static void cdatagcp_finalize(CDataObject_gcp *cd)
+{
+    PyObject *destructor = cd->destructor;
+    PyObject *origobj = cd->origobj;
+    cd->destructor = NULL;
+    cd->origobj = NULL;
+    gcp_finalize(destructor, origobj);
+}
+#endif
+
+static void cdatagcp_dealloc(CDataObject_gcp *cd)
+{
+    PyObject *destructor = cd->destructor;
+    PyObject *origobj = cd->origobj;
+    cdata_dealloc((CDataObject *)cd);
+
+    gcp_finalize(destructor, origobj);
 }
 
 static int cdatagcp_traverse(CDataObject_gcp *cd, visitproc visit, void *arg)
@@ -2814,6 +2833,9 @@
     0,                                          /* tp_setattro */
     0,                                          /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES  /* tp_flags */
+#ifdef Py_TPFLAGS_HAVE_FINALIZE
+                       | Py_TPFLAGS_HAVE_FINALIZE
+#endif
                        | Py_TPFLAGS_HAVE_GC,
     0,                                          /* tp_doc */
     (traverseproc)cdatagcp_traverse,            /* tp_traverse */
@@ -2826,6 +2848,25 @@
     0,                                          /* tp_members */
     0,                                          /* tp_getset */
     &CData_Type,                                /* tp_base */
+#ifdef Py_TPFLAGS_HAVE_FINALIZE  /* CPython >= 3.4 */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    0,                                          /* tp_new */
+    0,                                          /* tp_free */
+    0,                                          /* tp_is_gc */
+    0,                                          /* tp_bases */
+    0,                                          /* tp_mro */
+    0,                                          /* tp_cache */
+    0,                                          /* tp_subclasses */
+    0,                                          /* tp_weaklist */
+    0,                                          /* tp_del */
+    0,                                          /* version_tag */
+    (destructor)cdatagcp_finalize,              /* tp_finalize */
+#endif
 };
 
 /************************************************************/
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to