Hi

I've been getting some interpeter aborts running pygtk code. (pygtk
2.4.0 with python 2.3.4)

% python buggy_pygtk_testcase.py
Fatal Python error: PyThreadState_Get: no current thread
Aborted

I've reduced the problem to this code:
--
import pygtk
pygtk.require("2.0")
import gtk

import gc
import threading
import time

gtk.gdk.threads_init()

class GarbageCollectingThread(threading.Thread):

    def __init__(self, attempts=3):
        threading.Thread.__init__(self)
        self.attempts = attempts
        self.setDaemon(True)
        
    def run(self):
        for a in range(self.attempts):
            gc.collect()
            time.sleep(1)

class ButtonClickedHandler:

    def clicked(self, *args):
        print "foo"

collecting_thread = GarbageCollectingThread()
collecting_thread.start()
button = gtk.Button("Foo")
button.connect("clicked", ButtonClickedHandler().clicked)
# make button and so clicked handler available for garbage collection
button = None 
collecting_thread.join()
--
After running the code in gdb with a debug version of pygtk I found that
the code introduced to get round the apparent problems in the PyGILState
APIs is relevant.

http://cvs.gnome.org/viewcvs/gnome-python/pygtk/gobject/gobjectmodule.c?rev=1.151&view=markup

It seems as if garbage collection within a python thread of a pygtk
object that itself has a reference to a python object will cause the
interpeter to abort.

This is because the pygtk code that is called when gtk calls back to
remove the object referenced by the gtk object, that is itself being
removed, doesn't properly restore the current python thread state.

If the example code is run with the PYGTK_USE_GIL_STATE_API environment
variable set (or a version of python that satisfies PY_HEXVERSION >=
0x020400A4) then the python thread state is restored and interpreter
doesn't abort. This is because the PyGILState_Ensure is being used
rather than the erroneous pygtk work around.

I'm not sure what the best solution is because I'm not clear why the
pygtk code is trying to avoid the PyGILState APIs.

cheers,
Graham


_______________________________________________
pygtk mailing list   [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to