[Cython] nogil doesn't seem to work when defined on extern cpp functions

Stefan Behnel stefan_ml at behnel.de
Wed May 8 20:48:29 CEST 2013


Hi,

this question is better suited for the cython-users mailing list.

Ryan Pessa, 08.05.2013 20:09:
> I ran into an interesting problem today. It doesn't seem like Cython
> respects the `nogil` statement on extern cpp functions. I am trying to use
> a blocking I/O function, and am running it in secondary thread so I can use
> another library function to cancel it.
> 
> I have tried it both on the `extern` line:
>     cdef extern from "digitalpersona/dpfp_api.h" nogil:
>         uint32_t DPFPGetEvent(dp_uid_t* pDevUID, dp_device_event_t**
> ppEvent, uint32_t uTimeoutMsec)
> and on the function itself:
>     cdef extern from "digitalpersona/dpfp_api.h" nogil:
>         uint32_t DPFPGetEvent(dp_uid_t* pDevUID, dp_device_event_t**
> ppEvent, uint32_t uTimeoutMsec) nogil
> 
> Either way, this statement still blocks other threads:
>     res = dpfp_api.DPFPGetEvent(pIdDev, &pEvent,
> dpfp_api.DP_TIMEOUT_INFINITE)
> While this statement does not:
>     with nogil:
>         res = dpfp_api.DPFPGetEvent(pIdDev, &pEvent,
> dpfp_api.DP_TIMEOUT_INFINITE)
> All variables used (res, pIdDev, pEvent) are C variables.
> 
> Obviously this is not a huge issue, as I can bypass the GIL using `with
> nogil`. But I figured it would be a good idea to report it anyway.

Declarations won't implicitly free the GIL for you. They just state that
the function doesn't need the GIL and can thus be called safely from within
a "nogil" block. Freeing the GIL is an explicit operation that is left to
the user.

Otherwise, you'd end up with ambiguous code semantics. Imaging you'd call
two functions in a row that are both declared nogil - should Cython lock
the GIL in between or not?

Stefan



More information about the cython-devel mailing list