<div>I've been writing a C++ application with an embedded Python interpreter, for which I am using Stackless Python 2.6.5.  I am using Boost to wrap my objects.  I had the great fortune of running head-first into the GIL when I started calling back into Python objects that were implementing some C++ interfaces.  These calls are coming in from a variety of threads in the C++ runtime, and the rest was history.</div>
<div><br></div><div>Hence, I am no stranger to our friend "PyThreadState_Get: no current thread." I've learned how to acquire the GIL in my wrappers and there was peace in the land again.</div><div><br></div>
<div>The problem this time is my call stack takes me right to the thread with the Stackless Python runtime in it, and not some imposter thread.  I see the runtime itself trying to secure the thread state, and there I hit the error.</div>
<div><br></div><div>In my Python code, I have this main thread running a horrific poll loop:</div><div><br></div><div><div>        # Busy loop while waiting for escape key</div><div>        while not self.stopLoop:</div><div>
            stackless.schedule()</div></div><div><br></div><div>Indeed this is a terrible way to do it, but it's a stop gap while I bring up a lot of other code.  I am pretty sure if I improved on this with condition variables or monitors or whatever Stackless uses, that I would still have the problem--I may yet try this while waiting for some hints just to reduce the amount of bile I imagine that code is generating.</div>
<div><br></div><div>The callback looks like this:</div><div><div>    def ReceiveInputEvent(self, inputType, eventData):</div><div>        print "Received input event"</div><div>        if inputType == CECControlTypes.QuitProgram:</div>
<div>            print "Setting stopLoop = True"</div><div>            self.stopLoop = True</div></div><div><br></div><div>Right now when I hit escape, it will come back multiple times so long as I have held it down.  That wasn't my goal, and I want to work on that, but it makes the problem much more chronic at the moment so I'm keeping it.  It'll crash sometimes in the middle of this code, and sometimes after I have cleared it.  The wrapper is doing this:</div>
<div><br></div><div><div><span class="Apple-tab-span" style="white-space:pre">  </span>PyGILState_STATE gstate = PyGILState_Ensure();</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>this->get_override("ReceiveInputEvent")(type, eventData);</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>PyGILState_Release(gstate);<span class="Apple-tab-span" style="white-space:pre"> </span></div><div><br></div></div><div>This code is behaving for me; the Ensure call succeeds and I don't see issues with the release.  Maybe I'm not checking for them?  I have set breakpoints at the Ensure and Release and I see the error can also happen once I am clear of the Release.</div>
<div><br></div><div>One thing is for certain--if I don't ever trigger that callback, everything is fine, or at least I don't get that error.</div><div><br></div><div>I'm assuming that somehow Stackless didn't get the memo that I stole the interpreter for a moment for another thread.  Is there some special rules I need to honor with it when I do this crazy stuff?</div>
<div><br></div><div>Environment:]</div><div>I'm using Boost 1.47</div><div>My OS is Vista 64-bit</div><div>I'm using Visual Studio 2010</div><div>I'm building and running with debug symbols on, including Python.</div>
<div><br></div><div>Stackless Python startup string:</div><div>Python 2.6.5 Stackless 3.1b3 060516 (release26-maint, Feb 15 2012, 09:11:40) [MSC v.1600 32 bit (Intel)] on win32</div><div><br></div><div>I am using a 2.6 one since it mates up with Boost well.  If we have good reason to move on to a newer one, I have to see what mates with Boost now and try to work with that.  But let's say trying a new version of Stackless is nontrivial.  I'm also assuming I just missed something and all would be well.</div>