pygtk threads y segmentation fault

Daniel Garcia Moreno dani en danigm.net
Sab Nov 22 22:45:00 CET 2008


Hola a todos, tengo una aplicación en pygtk que hace una llamada
bloqueante a un servicio xmlrpc y para que no se quede colgado mientras
tanto, hago esta llamada en un thread.

Es bien sabido que pygtk no se lleva muy bien con los threads y por eso
me he mirado la faq [1] de pygtk y he rodeado el código dentro del
thread con gtk.gdk.threads_enter()/gtk.gdk.threads_leave(), pero me
sigue fallando la aplicación de forma aleatoria.

Si alguien quiere probar la aplicación puede descargarla con bzr [2]:
bzr branch http://repo.danigm.net/sweetgtk
Falla al pulsar alternativamente los botones home e index de forma
rápida, o al inicio, que es cuando se llama al thread.

Aquí el código del thread:

    def threaded_refresh(self):
        try:
            gtk.gdk.threads_enter()
            get_sweets = self.sweet.get_last_comments
            if self.show == 'index':
                user = 'index'
            elif self.show == 'home':
                user = self.user
                get_sweets = self.sweet.get_last_followings
            elif self.show == 'other':
                user = self.other.get_text()
                if not user: user = 'index'
            try:
                latest = get_sweets(user)
            except Exception, e:
                self.update_progress = False
                self.thread_started = False
                latest = []
                self.create_entry('gtk-dialog-error', str(e),
error=True)
                
            latest.reverse()
            for last in latest:
                if not self.last or last.created > self.last.created:
                    self.last = last

                    name = self.last.user 
                    text = self.last.sweet + '\n(%s)' %
self.last.created.ctime()
                    image_path = self.last.avatar

                    path = os.path.join(self.CACHE,
                            os.path.basename(image_path))
                    if not os.path.exists(path):
                        
                        file = urllib2.urlopen(image_path)
                        file2 = open(path, 'w')
                        file2.write(file.read())
                        file2.close()
                        file.close()
                    
                    self.create_entry(path, name + ': ' + text)
        finally:
            gtk.gdk.threads_leave()

        self.first = False
        self.update_progress = False
        self.thread_started = False

    def refresh(self):
        '''
        Show sweets from sweetter
        '''
        if not self.thread_started:
            self.thread_started = True
            t = threading.Thread(target=self.threaded_refresh)
            t.start()
        return True

Este es el error que me sale por pantalla:

python: xcb_lock.c:33: _XCBUnlockDisplay: La declaración
`xcb_get_request_sent(dpy->xcb->connection) == dpy->request' no se
cumple.
Locking assertion failure.  Backtrace:
#0 /usr/lib/libxcb-xlib.so.0 [0xb6f697a7]
#1 /usr/lib/libxcb-xlib.so.0(xcb_xlib_lock+0x2e) [0xb6f6994e]
#2 /usr/lib/libX11.so.6 [0xb709bdf9]
#3 /usr/lib/libX11.so.6(XUngrabPointer+0x25) [0xb7091b65]
#4 /usr/lib/libgdk-x11-2.0.so.0(gdk_display_pointer_ungrab+0x99)
[0xb73bbc69]
#5 /usr/lib/libgdk-x11-2.0.so.0(gdk_pointer_ungrab+0x1a) [0xb7396eea]
#6 /usr/lib/gtk-2.0/modules/libgnomebreakpad.so [0xb6c62623]
#7 /usr/lib/gtk-2.0/modules/libgnomebreakpad.so [0xb6c62bb5]
#8 [0xb8064400]
#9 /lib/libc.so.6(abort+0x188) [0xb7d6b058]
#10 /lib/libc.so.6(__assert_fail+0xee) [0xb7d6265e]
#11 /usr/lib/libX11.so.6 [0xb709bd8e]
#12 /usr/lib/libXrender.so.1(XRenderCompositeTrapezoids+0x1f4)
[0xb70152c4]
#13 /usr/lib/libcairo.so.2 [0xb7293fdd]
#14 /usr/lib/libcairo.so.2 [0xb7278bc1]
#15 /usr/lib/libcairo.so.2 [0xb727c7c5]
#16 /usr/lib/libcairo.so.2 [0xb727b8a7]
#17 /usr/lib/libcairo.so.2 [0xb727c2ad]
#18 /usr/lib/libcairo.so.2 [0xb727c94b]
#19 /usr/lib/libcairo.so.2 [0xb7278fb6]
python: xcb_lock.c:77: _XGetXCBBuffer: La declaración `((int) ((xcb_req)
- (dpy->request)) >= 0)' no se cumple.
Multiple segmentation faults occurred; can't display error dialog


[1] http://faq.pygtk.org/index.py?req=index
[2] http://bazaar-vcs.org/
------------ próxima parte ------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: Esta parte del mensaje está firmada	digitalmente
URL: <http://mail.python.org/pipermail/python-es/attachments/20081122/7358d6b4/attachment.pgp>
------------ próxima parte ------------
_______________________________________________
Lista de correo Python-es 
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes


Más información sobre la lista de distribución Python-es