PDA

View Full Version : QThread and QTcpSocket



^NyAw^
9th May 2008, 10:58
Hi,

I have an application that has a QTcpServer. When a incoming connection comes, it creates a QThread passing the socketDescriptor to it. On "start", the QThread creates a QTcpSocket with this descriptor. The communication between client and server works, but when the client closes the communication and the server deletes the QThread(and the QThread deletes the QTcpSocket), the application crash:

"ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different threads. ..."

On console out, when the QThread sets the descriptor to the socket I recive this messages:
"QObject: Cannot create children for a parent that is in a different thread"
"(Parent is CThread(01901048), parent's thread is QThread(01738258), current thread is CThread(01901048)"



void CServer::incomingConnection(int iSocketDescriptor)
{
CThread* pCThread = new CThread(this,iSocketDescriptor);
bool bC = connect(pCThread, SIGNAL(finished()), pCThread, SLOT(deleteLater()));
pCThread->start();
}




void CThread::run()
{
m_pqSocket = new QTcpSocket(this);
if (!m_pqSocket->setSocketDescriptor(m_iSocketDescriptor))
{
emit error(m_pqSocket->error());
return;
}
bool bC = connect(m_pqSocket,SIGNAL(readyRead()),this,SLOT(r eadData()));
bool bC2 = connect(m_pqSocket,SIGNAL(disconnected()),this,SLO T(disconnected()));
exec();
}

CThread::~CThread()
{
m_pqSocket->disconnectFromHost();
m_pqSocket->waitForDisconnected();
delete (m_pqSocket); //Here the application crash
}


I'm doing a similar code as the "threadedfortuneserver" example.

Thanks,

wysota
9th May 2008, 11:07
The QThread object lives in the thread which created the object (so not the thread the QThread object represents), thus creating an object with the thread object as the parent within the run() method is not possible. Either skip the parent pointer of the socket (and delete the object before leaving run()) or move the QThread object to its own thread.

^NyAw^
9th May 2008, 11:42
Hi,

Thanks, It's working now.

I thought that the objects created in the run method of the Thread will create the objects having the QThread as parent.

Thanks,

jpn
12th May 2008, 13:06
A couple of additional notes:

Those connections established in CThread::run() should be enforced as Qt::DirectConnection. Otherwise the corresponding slots get executed in "wrong" thread context and using m_pqSocket in those slots will eventually lead to crashes.
The destructor of CThread shouldn't access m_pqSocket which lives in another thread.

Easiest way to avoid aforementioned problems is to implement such functionality in QTcpSocket subclass instead of the QThread subclass.