Questions on the C Thread API

Duncan Booth duncan at NOSPAMrcp.co.uk
Mon Apr 15 08:48:28 EDT 2002


Phil Thompson <phil at river-bank.demon.co.uk> wrote in 
news:mailman.1018871909.16619.python-list at python.org:

> Currently, any C++ method that might block effectively has a call to
> PyEval_SaveThread() before it and a call to PyEval_ReleaseThread() after
> it. Any C++ virtual method that has been re-implemented in Python first
> checks to see if it already has the global lock, and acquires it if it
> doesn't. The Python method is then evaluated, and the global lock
> released if it had previously been acquired. The check if the lock has
> already been acquired is necessary because I only release the lock on a
> small subset of C++ methods, ie. those that might block, which I do for
> reasons of efficiency.

PyEval_SaveThread and PyEval_ReleaseThread both release the 
interpreter lock. Did you mean PyEval_RestoreThread for the second one of 
these?

Anyway, when you are going to do something that might block you save the 
thread state and restore it later. I presume you save the state in some 
thread local storage because you could have several threads all suspended 
in this way.
> 
> All the above works fine, so long as all the C++ calls are made from the
> same thread. With the support of the Qt thread classes, that assumption
> is no longer valid.
> 
> Therefore, just before calling the Python code that re-implements a C++
> virtual method, the global lock has to be acquired, and the correct
> thread state restored. However, to prevent a deadlock the thread state
> can only be restored if it is not the current one, but there is no way
> to get the value of the current thread state without having acquired the
> global lock. Catch 22.

Get the saved thread state for the current thread. If you don't have one 
then by definition you already have the global lock. If you have one then 
call PyEval_RestoreThread to get the lock and set the state and clear your 
saved state to NULL. Remember whether or not you had a thread state around 
the callback and only save the state/release the lock if you previously 
restored a state.

-- 
Duncan Booth                                             duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?



More information about the Python-list mailing list