[Pyrex] nogil checking

Stefan Behnel stefan_ml at behnel.de
Thu Jun 5 15:05:17 CEST 2008


Hi,

I merged most of the nogil checking code from Pyrex into Cython, but I noticed
that it will break a lot of code. It makes Cython pretty strict about what is
allowed in a nogil function and what isn't. It even checks function pointer
assignments for "nogil" matches, so you really have to take care when
declaring and assigning callback functions.

The problem is that it's not always possible to fix such code, as "nogil" is
more about semantics than about syntax. In lxml, I use the same (SAX2)
callback function struct in a number of places, and I sometimes release the
GIL when passing it into libxml2 and sometimes I keep holding it, depending on
what I consider faster. The related callback functions are designed to handle
exactly their specific case, so some are declared "with GIL" and others do not
have a declaration as they know the GIL will be held when they get called. So
this requires an explicit cast now. And a cast always holds the risk of
shadowing real bugs.

Here's an example. Say, we have three functions that implement a callback:

    cdef void c1():
        # Python stuff
    cdef void c2() with GIL:
        # Python stuff
    cdef void c3() nogil:
        # C stuff

For the following callback function type

    ctypedef void (*callback)()

all of the three functions should be assignable, as we know we hold the GIL
when it's called, whereas for

    ctypedef void (*callback)() nogil

only c2 and c3 should work, as we know we do not hold it. Pyrex currently
distinguishes "nogil" and "with GIL" functions generally from normal cdef
functions, so c2 and c3 cannot be assigned to the first callback pointer. I
consider that a bug in Pyrex. Below is a very simple patch that fixes the
problem above. It's a bit hackish in that it's not restricted to an
assignment, but it seems to work for me.

Stefan


diff -r d69b3342f623 Cython/Compiler/PyrexTypes.py
--- a/Cython/Compiler/PyrexTypes.py     Thu Jun 05 12:20:27 2008 +0200
+++ b/Cython/Compiler/PyrexTypes.py     Thu Jun 05 14:09:21 2008 +0200
@@ -695,7 +695,7 @@ class CFuncType(CType):
             return 0
         if not self.same_calling_convention_as(other_type):
             return 0
-        if self.nogil != other_type.nogil:
+        if self.nogil and not other_type.nogil:
             return 0
         return 1





More information about the Pyrex mailing list