mapnik/mapnik — Issue #1063: Reacquiring python GIL for overridden functions
Author: herm
Created: 2012-02-05 00:12:40+00:00
State: open
Labels: mustfix, python bindings, text placement

Code in 2f144d6ccb6ff791dab2e021f81e820996b769da crashes python interpreter when trying to override FormatingTextNode::apply() in python.

After quite a bit of debugging I found that the problem is that render() in mapnik_python.cpp releases the global interpreter lock (GIL) by calling ```Py_BEGIN_ALLOW_THREADS```. Without the lock being held no python instructions must be executed. So the lock must be reacquired before calling the overridden function. However ```Py_BEGIN_ALLOW_THREADS``` stores the thread state in a local variable which isn't accessible while calling the overridden function but it is required to call ```Py_END_ALLOW_THREADS```.

So this thread state would have to go to some kind of thread-local storage to accessible in the python bindings. Boost provides a class for this, but perhaps better solutions exist.

_Are there better ideas how to handle this?_

### References:

* http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock
* http://www.boost.org/doc/libs/1_35_0/doc/html/thread/thread_local_storage.html