Comments below.

On 19/10/2006, at 8:55 PM, Graham Dumpleton wrote:

For such issues, by all means just send the email direct to the mailing list. I have copied this back onto the list and I'll do some research into what
you describe.

BTW, I don't use Windows, but there are others on the list who do and it
may help if you can explain what methodology you are using to see the
Win32 handle leaks. This will help others to replicate it and then track it
down.

Thanks.

Graham

On 19/10/2006, at 8:50 PM, Jeff Robbins wrote:

Graham,

I apologize in advance for not understanding the email etiquette for the list, so I'm emailing you directly. (I subscribed to the python-dev list and email the faq magic subject but the reply said "no info".) Anyway...

I know of two leaks in Python 3.2.10 / Apache 2.2.3 that I would dearly love to get fixed. One of them I have identified the source and made a change to my copy and it works (and comports with the python embedding documentation) so I was hoping you could either get it in or help me understand how I can get it applied.

The first leak is if you use the _repr_ function of a dict or list (which is as simple as using str([]) in your mod_python handler!) The repr functions use a dict in the python threadstate to avoid some recursion problem. This dict is allocated only on demand, so while I found str([]) (or a str of any dict or list) to cause its allocation, there may be other user code things you can do to get it allocated. To free it, the python embedder need to call "PyThreadState_Clear" before calling "PyThreadState_Delete". Yet mod_python.c release_interpreter() does not call "PyThreadState_Clear". The fixed version of release_interpreter is this:

static void release_interpreter(void)
{
PyThreadState *tstate = PyThreadState_Get();
#ifdef WITH_THREAD
PyEval_ReleaseThread(tstate);
#else
PyThreadState_Swap(NULL);
#endif
// JSR
PyThreadState_Clear(tstate);
PyThreadState_Delete(tstate);
}

Still looking at this, but where you do it looks to be wrong. The documentation
below for PyThreadState_Clear() says:

  The interpreter lock must be held.

Where you are calling that function, it isn't. It may need to be moved to before
the call to PyEval_ReleaseThread(). Yes/No?

The Python embedded doc is clear that this is the correct thing to do:
http://docs.python.org/api/threads.html
...
       void PyThreadState_Clear( PyThreadState *tstate)

Reset all information in a thread state object. The interpreter lock must be held.

       void PyThreadState_Delete( PyThreadState *tstate)

Destroy a thread state object. The interpreter lock need not be held. The thread state must have been reset with a previous call to PyThreadState_Clear().

Graham

Reply via email to