/*
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

Reply via email to