/* Is this a bug in Py_NewInterpreter? 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 CCriticalSection lock if (!Py_IsInitialized()) { Py_Initialize(); PyEval_InitThreads(); // global pointer to the main PyThreadState object mainThreadState = PyThreadState_Get(); PyEval_ReleaseLock(); } cs.Unlock(); } ASSERT(Py_IsInitialized()); ASSERT(PyEval_ThreadsInitialized()); ASSERT(mainThreadState); threadnum++; // get the global lock PyEval_AcquireLock(); PyGILState_STATE gstate; gstate = PyGILState_Ensure(); // Is tis necessary? PyThreadState_Swap(mainThreadState); PyThreadState* nts = Py_NewInterpreter(); /* 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_Swap(tstate); Inside PyThreadState_Swap the code uses another way 'PyGILState_GetThisThreadState()' 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_DEBUG) && defined(WITH_THREAD) if (new) { PyThreadState *check = PyGILState_GetThisThreadState(); 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_NewInterpreter is implemented? Thanks Martin PS: Below the rest of my simple test worker thread function. */ ASSERT(nts == PyThreadState_Get()); // lock (already locked) - swap in thread state - swap out thread state - unlock init_testclass(); int ret = 0; ret = PyRun_SimpleString("import sys"); ret = PyRun_SimpleString("class redir:\n def __init__(self, id):\n self.id = id\n def write(self, s):\n f = open('stdoutputs_%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_SimpleString(str); ret = PyRun_SimpleString("sys.stderr = r"); sprintf(str,"s = redir('0x%x')", &nts); ret = PyRun_SimpleString(str); ret = PyRun_SimpleString("sys.stdout = s"); ret = PyRun_SimpleString("import testclass"); ret = PyRun_SimpleString("t = testclass.testclass()"); sprintf(str,"print 't = ', t "); ret = PyRun_SimpleString(str); ret = PyRun_SimpleString("print t.run(10)"); Py_EndInterpreter(nts); PyGILState_Release(gstate); PyEval_ReleaseLock(); return 0; } -- http://mail.python.org/mailman/listinfo/python-list