Caveat on GIL
There is a caveat to remember when using gil
. In our callbacks, we need to acquire the GIL on each callback before we call any Python code; otherwise, we will segfault and get really confused. So, if you look into each of the libevent
callbacks when calling the Cython functions, you have the following:
PyGILState_STATE gilstate_save = PyGILState_Ensure(); readcb (client, (char *)data); PyGILState_Release(gilstate_save);
Notice that this is also called on the other two callbacks—firstly on the discb
callback:
PyGILState_STATE gilstate_save = PyGILState_Ensure(); discb (client, NULL); PyGILState_Release(gilstate_save);
Finally, on the connect callback, we must be a little safer and call it this way:
PyGILState_STATE gilstate_save = PyGILState_Ensure(); if (!conncb (NULL, inet_ntoa (client_addr.sin_addr))) { … } else close (client_fd); PyGILState_Release(gilstate_save);
We have to do this since we executed this with nogil
from Cython. We need to acquire gil...