deleting serialPort causes this message in debug builds:
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread c0a528. Receiver '' (of type 'QSerialPort') was created in thread c76850", file kernel\qcoreapplication.cpp, line 532
The actual error is triggered in ~QSerialReader when Main window is closed. Here's the code.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
runnerThread=new QThread(this);
/* - connect thread start signal to qrunnerthread's runLoop()
this starts the main job loop
- connect thread finished signal to mainwindows' deleteLater
to ensure proper deletion */
qDataReader = new QDataReader();
connect(runnerThread, SIGNAL(started()), qRunnerThread, SLOT(runLoop()));
connect(runnerThread, SIGNAL(finished()), this, SLOT(deleteLater()));
qDataReader->moveToThread(runnerThread);
runnerThread.start();
}
MainWindow::~MainWindow()
{
runnerThread->exit();
}
//slot that runs when thread is started
void QDataReader::runLoop() {
/* this code runs in different thread than QDataReader */
//serialPort parent will be QThread (runnerThread)
serialReader=new QSerialReader(this);
while(doStuff) {
QString data=serialReader.readData();
emit dataReceived(data);
}
}
QDataReader::~QDataReader() {
delete runner;
}
QSerialReader::QSerialReader(QObject* parent) {
//serialPort parent will be QSerialReader
serialPort = new QSerialPort(this);
}
QSerialReader::~QSerialReader() {
/*
deleting serialPort causes this message in debug builds:
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread c0a528. Receiver '' (of type 'QSerialPort') was created in thread c76850", file kernel\qcoreapplication.cpp, line 532
*/
delete serialPort;
}
edit1: peppe's suggestion:
If I change QSerialReader to a member in QDataReader the problem is gone. BUT when opening port with QSerialPort::open this error comes up:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QSerialPort(0xdf6930), parent's thread is QThread(0xd8a528), current thread is QThread(0xdf6850)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QSerialPort(0xdf6930), parent's thread is QThread(0xd8a528), current thread is QThread(0xdf6850)
QSerialPort::open(xx) is called inside serialReader.readData();
So still... some nasty problem. I did not have issues like this when I coded in Java a few years ago.
stack trace when CSerialReader::openPort is called. this calls QSerialPort::open. Clearly this is run in other thread than main.
0 CSerialReader::openPort serialreader.cpp 480 0xff7211
1 CSerialReader::readData serialreader.cpp 209 0xff4e1d
2 QDataReader::runLoop qdatareader.cpp 138 0xffa3fe
3 QDataReader::qt_static_metacall moc_qdatareader.cpp 62 0x1040824
4 QMetaObject::activate qobject.cpp 3539 0x669b0e14
5 QThread::started moc_qthread.cpp 113 0x66a29979
6 QThreadPrivate::start qthread_win.cpp 345 0x66816918
7 _callthreadstartex threadex.c 314 0xf71a293
8 _threadstartex threadex.c 297 0xf71a224
9 BaseThreadInitThunk kernel32 0x74cd3677
10 __RtlUserThreadStart ntdll32 0x76f9c002
11 _RtlUserThreadStart ntdll32 0x76f9bfd5
stack trace when CSerialReader is created (as member variable). This is called in main thread.
0 CSerialReader::CSerialReader Runner.cpp 48 0x9d3d14
1 QDataReader::QDataReader qdatareader.cpp 10 0x9d8fa4
2 MainWindow::MainWindow mainwindow.cpp 72 0x9c61eb
3 main main.cpp 105 0x9c4adc
4 WinMain qtmain_win.cpp 131 0xa273ba
5 __tmainCRTStartup crtexe.c 547 0xa269e0
6 WinMainCRTStartup crtexe.c 371 0xa2676f
7 BaseThreadInitThunk kernel32 0x74cd3677
8 __RtlUserThreadStart ntdll32 0x76f9c002
9 _RtlUserThreadStart ntdll32 0x76f9bfd5