[pypy-commit] cffi default: issue #246: trying to be more robust against CPython's fragile

arigo pypy.commits at gmail.com
Sat Feb 6 14:26:18 EST 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r2619:bdcc6eeb3de4
Date: 2016-02-06 20:25 +0100
http://bitbucket.org/cffi/cffi/changeset/bdcc6eeb3de4/

Log:	issue #246: trying to be more robust against CPython's fragile
	interpreter shutdown logic

diff --git a/c/call_python.c b/c/call_python.c
--- a/c/call_python.c
+++ b/c/call_python.c
@@ -115,6 +115,7 @@
 static int _update_cache_to_call_python(struct _cffi_externpy_s *externpy)
 {
     PyObject *interpstate_dict, *interpstate_key, *infotuple, *old1, *new1;
+    PyObject *old2;
 
     interpstate_dict = _get_interpstate_dict();
     if (interpstate_dict == NULL)
@@ -127,14 +128,17 @@
     infotuple = PyDict_GetItem(interpstate_dict, interpstate_key);
     Py_DECREF(interpstate_key);
     if (infotuple == NULL)
-        return 1;    /* no ffi.def_extern() from this subinterpreter */
+        return 3;    /* no ffi.def_extern() from this subinterpreter */
 
     new1 = PyThreadState_GET()->interp->modules;
     Py_INCREF(new1);
+    Py_INCREF(infotuple);
     old1 = (PyObject *)externpy->reserved1;
+    old2 = (PyObject *)externpy->reserved2;
     externpy->reserved1 = new1;         /* holds a reference        */
-    externpy->reserved2 = infotuple;    /* doesn't hold a reference */
+    externpy->reserved2 = infotuple;    /* holds a reference (issue #246) */
     Py_XDECREF(old1);
+    Py_XDECREF(old2);
 
     return 0;   /* no error */
 
@@ -213,9 +217,11 @@
         gil_release(state);
     }
     if (err) {
-        static const char *msg[2] = {
+        static const char *msg[] = {
             "no code was attached to it yet with @ffi.def_extern()",
-            "got internal exception (out of memory?)" };
+            "got internal exception (out of memory / shutdown issue)",
+            "@ffi.def_extern() was not called in the current subinterpreter",
+        };
         fprintf(stderr, "extern \"Python\": function %s() called, "
                         "but %s.  Returning 0.\n", externpy->name, msg[err-1]);
         memset(args, 0, externpy->size_of_result);


More information about the pypy-commit mailing list