/*
Is this a bug in Py_NewInterpret er?
The function below "MyThread" is instantiated from a windows worker
thread, but I don't
think that is relevant.
(I can try this on a linux box, but I would have to compile a python
library with debugging
enabled.)
The following code fragment throws an exception in a debug version of
python:
*/
UINT MyThread(LPVOID lpParam)
{
{
cs.Lock(); // this is a CCriticalSectio n lock
if (!Py_IsInitiali zed())
{
Py_Initialize() ;
PyEval_InitThre ads();
// global pointer to the main PyThreadState object
mainThreadState = PyThreadState_G et();
PyEval_ReleaseL ock();
}
cs.Unlock();
}
ASSERT(Py_IsIni tialized());
ASSERT(PyEval_T hreadsInitializ ed());
ASSERT(mainThre adState);
threadnum++;
// get the global lock
PyEval_AcquireL ock();
PyGILState_STAT E gstate;
gstate = PyGILState_Ensu re(); // Is tis necessary?
PyThreadState_S wap(mainThreadS tate);
PyThreadState* nts = Py_NewInterpret er();
/*
The exception is thrown inside the above function call:
This statement tries to swap the new threadstate 'tstate' with the
current one
save_tstate = PyThreadState_S wap(tstate);
Inside PyThreadState_S wap the code uses another way
'PyGILState_Get ThisThreadState ()' to find the current thread state and
compares this with the newly set thread state.
Naturally you would expect the two to be equal but that test fails:
#if defined(Py_DEBU G) && defined(WITH_TH READ)
if (new) {
PyThreadState *check = PyGILState_GetT hisThreadState( );
if (check && check != new)
Py_FatalError(" Invalid thread state for this thread");
}
#endif
The variable 'check' looks as if it is the 'previous' thread state, as
if changing the thread state
is not been done properly. Py_FatalError is called and that's the end.
Is there a mistake in my code, or is there something wrong in how
Py_NewInterpret er is implemented?
Thanks
Martin
PS: Below the rest of my simple test worker thread function.
*/
ASSERT(nts == PyThreadState_G et());
// lock (already locked) - swap in thread state - swap out thread
state - unlock
init_testclass( );
int ret = 0;
ret = PyRun_SimpleStr ing("import sys");
ret = PyRun_SimpleStr ing("class redir:\n def __init__(self, id):\n
self.id = id\n def write(self, s):\n f = open('stdoutput s_%s.txt' %
self.id, 'a')\n f.write('%s: %s' % (self.id, s))\n f.close()\n");
char str[100];
sprintf(str,"r = redir('0x%x')", &nts);
ret = PyRun_SimpleStr ing(str);
ret = PyRun_SimpleStr ing("sys.stderr = r");
sprintf(str,"s = redir('0x%x')", &nts);
ret = PyRun_SimpleStr ing(str);
ret = PyRun_SimpleStr ing("sys.stdout = s");
ret = PyRun_SimpleStr ing("import testclass");
ret = PyRun_SimpleStr ing("t = testclass.testc lass()");
sprintf(str,"pr int 't = ', t ");
ret = PyRun_SimpleStr ing(str);
ret = PyRun_SimpleStr ing("print t.run(10)");
Py_EndInterpret er(nts);
PyGILState_Rele ase(gstate);
PyEval_ReleaseL ock();
return 0;
}