Problems with PyGILState_Ensure () and PyGILState_Release ()

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Mathias Mamsch

    Problems with PyGILState_Ensure () and PyGILState_Release ()

    Hi all,

    i am writing a python extension in c++. In the extension a c++ thread
    calls back into python. I did it like this:

    ---- c++ code ----
    PyGILState_STAT E gstate;
    gstate = PyGILState_Ensu re ();

    .... do some work ...
    // call the python callback (Func)
    result = PyEval_CallObje ct(Func, arglist);
    .... so some cleanup ...

    PyGILState_Rele ase (gstate);
    return
    -----------------

    the callback is executed properly, but the PyGILState_Rele ase gives me the
    following error:
    "Fatal Python error: PyThreadState_D elete: tstate is still current"

    What can be wrong here? Any suggestions?
    In my understanding this error should not occur ... Is this a known bug
    maybe? I am using Python 2.4a1 under windows.

    Thanks in advance, Mathias Mamsch



  • Greg Chapman

    #2
    Re: Problems with PyGILState_Ensu re () and PyGILState_Rele ase ()

    On Fri, 13 Aug 2004 13:49:09 +0200, "Mathias Mamsch" <Domoran@yahoo. de> wrote:
    [color=blue]
    >Hi all,
    >
    >i am writing a python extension in c++. In the extension a c++ thread
    >calls back into python. I did it like this:
    >
    >---- c++ code ----
    >PyGILState_STA TE gstate;
    >gstate = PyGILState_Ensu re ();
    >
    >... do some work ...
    >// call the python callback (Func)
    >result = PyEval_CallObje ct(Func, arglist);
    >... so some cleanup ...
    >
    >PyGILState_Rel ease (gstate);
    >return
    >-----------------
    >
    >the callback is executed properly, but the PyGILState_Rele ase gives me the
    >following error:
    >"Fatal Python error: PyThreadState_D elete: tstate is still current"
    >
    >What can be wrong here? Any suggestions?
    >In my understanding this error should not occur ... Is this a known bug
    >maybe? I am using Python 2.4a1 under windows.
    >
    >Thanks in advance, Mathias Mamsch
    >
    >[/color]

    Looking at the code for PyGILState_Rele ase (in pystate.c), it looks like what
    must be happening is a disagreement between tcur->gilstate_count er and oldstate
    (tcur is the current thread state and oldstate is the parameter passed in).
    Specifically, you appear to be passing in something other than
    PyGILState_UNLO CKED (so PyEval_ReleaseT hread is not called, leaving tcur as
    still the current thread), but tcur->gilstate_count er is decremented to 0,
    causing the attempt to free tcur.

    So it looks like the cause could be either 1) something writing to gstate (in
    your code above) between the calls to PyGILState_Ensu re and PyGILState_Rele ase,
    or 2) something making an extra call to PyGILState_Rele ase (i.e., one not
    matched by a call to PyGILState_Ensu re). Could your code be doing either of
    those things?

    ---
    Greg Chapman

    Comment

    • Mathias Mamsch

      #3
      Re: Problems with PyGILState_Ensu re () and PyGILState_Rele ase ()

      Hi Greg, thanks for your answer ...

      I really need help with this, because till now I found no solution to my
      problem ... I always get FatalErrors, Deadslocks, or protection faults ...

      I created some example code for what I want to accomplish. I have a single
      thread which calls some C-Function which should call back into python.

      To your questions: no nowhere in *my* code ReleaseThread is called and I
      dont write to gstate either ...
      I dont understand the thread handling of python completely... Any ideas
      where - besides the Python docs - I can find some information about that ?

      Thanks Mathias Mamsch

      here is some example code which produces my problem.
      hope it helps to understand it ...

      -----------

      #include "python.h"
      #include <windows.h>

      #include <iostream>

      using namespace std;

      #define GETLOCK PyGILState_STAT E gstate; \
      gstate = PyGILState_Ensu re ();

      #define RELEASELOCK PyGILState_Rele ase (gstate);

      static DWORD Tid;

      static int CHandleFunction ()
      {
      GETLOCK
      // here will I callback to python ...
      cout << "Hello" << endl;
      RELEASELOCK

      return 0;
      }

      static PyMethodDef SpamMethods[] = {
      {NULL, NULL, 0, NULL} /* Sentinel */
      };

      // some C Thread which calls the Handler ...
      DWORD __stdcall WCThread (LPVOID lpThreadParamet er)
      {
      while (1)
      {
      CHandleFunction ();
      Sleep(500);
      }
      }

      PyMODINIT_FUNC initkdll(void)
      {
      Py_InitModule(" kdll", SpamMethods);
      // Create some C++ Thread for testing purposes
      CreateThread(NU LL,0,WCThread,N ULL,0,&Tid);
      }



      Comment

      Working...