One part of an application I'm developing needs to send some emails to a small group of people. Since it may take a little while to connect to the SMTP server and send the emails, I want to provide a progress bar during this operation. I've only barely used threading before, so using QThread to do it has proven somewhat difficult for me.
What happens now is that I can implement a test structure that works just fine, but then as soon as I try to create an object from the backend of my application to actually do any emailing operations, it crashes completely (as though it had segfaulted), dumping this to the console:
[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
python: ../../src/xcb_io.c:179: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed.
Aborted
The only relevant thread I found searching for these errors said something about the signals being implemented wrong (for PySide, PySide and QProgressBar update in a different thread), but in my case the signals work totally fine until I try to create that object (which isn't based on Qt classes at all).
Here's a simplified version of my GUI code:
class SendingDialog(QtGui.QDialog):
def __init__(self, parent, optsDict, cls, zid):
QtGui.QDialog.__init__(self)
self.form = Ui_Dialog()
self.form.setupUi(self)
# initialize some class variables...
self.beginConnect()
self.thread = WorkerThread()
self.thread.insertOptions(self.opts, self.cls, self.zid)
self.thread.finished.connect(self.endOfThread)
self.thread.serverContacted.connect(self.startProgress)
self.thread.aboutToEmail.connect(self.updateProgress)
self.thread.start()
def beginConnect(self):
# start busy indicator
def startProgress(self):
# set up progress bar
def updateProgress(self):
# increment progress bar
def endOfThread(self):
self.thread.quit()
self.reject()
class WorkerThread(QtCore.QThread):
serverContacted = QtCore.pyqtSignal(name="serverContacted")
aboutToEmail = QtCore.pyqtSignal(name="aboutToEmail")
def insertOptions(self, opts, cls, zid):
self.opts = opts
self.cls = cls
self.zid = zid
def run(self):
# upon running the following line, the application crashes.
emailman = db.emailing.EmailManager(self.opts, self.cls, self.zid)
If I put some dummy code into run()
that sleeps, emits the appropriate signals, or prints test values, everything works fine; but as soon as I try to instantiate the EmailManager, the whole thing crashes.
EmailManager
is an unremarkable class derived from object
, taking the parameters I've given it (opts
is a dictionary, cls
is a different type of similarly unremarkable object, and zid
is just a plain number). The constructor looks like this:
def __init__(self, optsDict, cls, zid):
self.opts = optsDict
self.cls = cls
self.historyItem = HistoryItem(zid)
self.studentsList = studentsInClass(cls)
self.connection = None
I'm constructing a couple of other objects based on the parameters, but other than that, nothing complicated or unusual is happening. The code in the db.emailing
module does not use Qt or threading at all.
I don't even know how to begin debugging this, so any advice as to what might be going on or how I could try to find out would be very much appreciated.
Edit: In case it's helpful, here's the backtrace from gdb (I don't know enough about what's going on to find it helpful):
Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffeb146700 (LWP 31150)]
0x00007ffff762acc9 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0 0x00007ffff762acc9 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007ffff762e0d8 in __GI_abort () at abort.c:89
#2 0x00007ffff7623b86 in __assert_fail_base (
fmt=0x7ffff7774830 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
assertion=assertion@entry=0x7ffff6a4420d "!xcb_xlib_unknown_req_in_deq", file=file@entry=0x7ffff6a441db "../../src/xcb_io.c", line=line@entry=179,
function=function@entry=0x7ffff6a446b0 "dequeue_pending_request")
at assert.c:92
#3 0x00007ffff7623c32 in __GI___assert_fail (
assertion=0x7ffff6a4420d "!xcb_xlib_unknown_req_in_deq",
file=0x7ffff6a441db "../../src/xcb_io.c", line=179,
function=0x7ffff6a446b0 "dequeue_pending_request") at assert.c:101
#4 0x00007ffff69d479c in ?? () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#5 0x00007ffff69d55c3 in _XReply ()
from /usr/lib/x86_64-linux-gnu/libX11.so.6
#6 0x00007ffff69bc346 in XGetWindowProperty ()
from /usr/lib/x86_64-linux-gnu/libX11.so.6
#7 0x00007ffff69bb22e in XGetWMHints ()
from /usr/lib/x86_64-linux-gnu/libX11.so.6
#8 0x00007ffff4c87c4b in QWidgetPrivate::setWindowIcon_sys(bool) ()
from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#9 0x00007ffff4c38405 in QWidget::create(unsigned long, bool, bool) ()
from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#10 0x00007ffff4c4086a in QWidget::setVisible(bool) ()
from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#11 0x00007ffff509956e in QDialog::setVisible(bool) ()
from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#12 0x00007ffff5c24b7c in ?? ()
from /usr/lib/python2.7/dist-packages/PyQt4/QtGui.so
#13 0x00007ffff5099026 in QDialog::exec() ()
from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#14 0x00007ffff5be5fb5 in ?? ()
from /usr/lib/python2.7/dist-packages/PyQt4/QtGui.so
#15 0x000000000049968d in PyEval_EvalFrameEx ()
#16 0x00000000004a090c in PyEval_EvalCodeEx ()
#17 0x0000000000499a52 in PyEval_EvalFrameEx ()
#18 0x00000000004a1c9a in ?? ()
#19 0x00000000004dfe94 in ?? ()
#20 0x00000000004dc9cb in PyEval_CallObjectWithKeywords ()
#21 0x000000000043734b in PyErr_PrintEx ()
#22 0x00007ffff186fd4d in ?? ()
from /usr/lib/python2.7/dist-packages/sip.so
#23 0x00007ffff14b2ece in ?? ()
from /usr/lib/python2.7/dist-packages/PyQt4/QtCore.so
#24 0x00007ffff45be32f in ?? ()
from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#25 0x00007ffff79c1182 in start_thread (arg=0x7fffeb146700)
at pthread_create.c:312
#26 0x00007ffff76ee47d in clone ()
at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111