[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