Memory leak in QTcpServer attending connections in different thread - c++

I'm developing a RPC server in Qt 4.7 on Windows 7.
In order to attend several executions at the same time every request run in a separate thread (as functions might be blocking). I inherited from QTcpServer and reimplemented the incomingConnection function, it looks like this:
void RpcServer::incomingConnection(int socketDescriptor){
QThread *thread = new QThread();
RpcServerConnection *client = new RpcServerConnection(socketDescriptor);
client->moveToThread(thread);
connect(thread, SIGNAL(started()), client, SLOT(init()));
connect(client, SIGNAL(finish()), thread, SLOT(quit()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
RpcServerConnection managed data exchange. The init method looks like this:
void RpcServerConnection::init(){
qDebug() << "ServerSocket(" << QThread::currentThreadId() << "): Init";
clientConnection = new QTcpSocket();
clientConnection->setSocketDescriptor(socketDescriptor);
connect(clientConnection, SIGNAL(readyRead()), this, SLOT(readFromSocket()));
connect(clientConnection, SIGNAL(disconnected()), this, SLOT(deleteLater()));
connect(this, SIGNAL(finish()), this, SLOT(deleteLater()));
}
Once all data is received and response is sent, finish signal is emited.
Debugging I can see that all threads and sockets are deleted. However, process memory increases with every new connection and it is not freed when it ends...
Do I have to free anything else when inheriting from QTcpServer?

The problem may be with a race/undefined calling order. RpcServerConnection::finish() is connected both to its deleteLater() slot, and to the thread's quit() slot. If the thread's quit slot is entered first, the thread will terminate immediately from the event loop, before anything can be done about the deferred deletion.
Instead of:
connect(client, SIGNAL(finish()), thread, SLOT(quit()));
try:
connect(client, SIGNAL(destroyed()), thread, SLOT(quit()));

Related

QFutureWatcher signal not working

My function, finishedCopy(), isn't being called when the QtConcurrent::run function copyFolder is finished. The copyFolder function does complete w/o errors.
QFutureWatcher<void> watcher;
connect(&watcher, SIGNAL(finished()), this, SLOT(MainWindow::finishedCopy()));
QFuture <void> future = QtConcurrent::run(this,&MainWindow::copyFolder,filepath,dir);
watcher.setFuture(future);
void MainWindow::finishedCopy()
{
QMessageBox::information(this,"","Done");
}
You need your watcher to live longer.. you are declaring your watcher in the stack, and so it it will get destroyed before the connection signal is emitted.
Try to declare QFutureWatcher watcher as a member variable in your MainWindow header and then connect the single to the slot in MainWindow constructor
Replace this:
connect(&watcher, SIGNAL(finished()), this, SLOT(MainWindow::finishedCopy()));
with that:
connect(&watcher, SIGNAL(finished()), this, SLOT(finishedCopy()));
Also, connect returns bool so you can always check if connection is succeded.

main thread cannot get signal form worker thread

This is part of the main.
This code create a worker and a workerthread.
The worker is moved to the workerthread.
The worker is then waiting for the signal to ask it to work.
The worker emit a signal with result when job done.
The main supposed to catch that signal and initialize a variable in the main.
main()
{.........
// This is the variable to be changed
variableToGetFromWorker = 0;
qDebug() << "Main thread: " << QThread::currentThreadId();
QThread workerThread;
worker* stupidTom = new stupidTom(number);
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, &workerThread, &QObject::deleteLater);
connect(&workerThread, SIGNAL(start()), stupidTom, SLOT(doJob()));
connect(stupidTom, SIGNAL(jobDone(int)), this, SLOT(jobDone(int)));
workerThread.start();
workerThread.wait();
...........}
// This is a slot at main. Suppose to catch the signal from the worker
void main::jobDone(int result)
{
qDebug() << "Changing variable";
variableToGetFromWorker = result;
}
This is the doJob slot of the worker.
void worker::doJob()
{
qDebug() << "worker::doJob invoked.";
qDebug() << "worker Thread:" << QThread::currentThreadId();
// Doing Job here
emit jobDone(result);
}
It is the qDebug result
Main thread: 0x7ffff7fc6780
worker::doJob invoked.
worker Thread: 0x7fffdab44700
In Debug mode, I find that the program is stop at workerThread.wait()
and never go to main::jobDone(int result). What is the reason?
Little editing on the main code:
QThread workerThread;
worker* stupidTom = new stupidTom(number);
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, &workerThread, &QObject::deleteLater);
connect(&workerThread, SIGNAL(started()), stupidTom, SLOT(doJob()));
connect(stupidTom, SIGNAL(jobDone(int)), this, SLOT(jobDone(int)));
connect(stupidTom, SIGNAL(jobDone(int)), &workerThread, SLOT(quit()));
workerThread.start();
workerThread.wait();
As long as signals supposed to invoke slots. That won't be working on wait() on the main thread that supposed to run the slot or specifically jobDone signal.
Make sure to understand the difference between QThread::exec() and QThread::wait() in your application. Normally in the real app your thread would be looping (running) while the thread that launched it is still looping as well. The loop is implemented in protected QThread::exec() method. We usually don't need to call exec() explicitly but we need to allow the thread to run. You can do that by making main function to use QEventLoop for looping:
int main()
{
//...
workerThread.start();
QEventLoop eventLoop;
// here you will probably want to hook-up QEventLoop::quit() slot
// to eventually quit the process
int returnCode = eventLoop.exec();
//...
return returnCode;
}
And this is also wrong:
connect(&workerThread, SIGNAL(start()), stupidTom, SLOT(doJob()));
Instead you should create your own job object and do QObject::moveToThread for it. Here is a nice article about it. So it should rather look like:
connect(&workerThread, SIGNAL(started()), stupidTom, SLOT(doJob()));
I likely understand why you attempted to run the thread that way as above. It is similar to many C++ examples. You can also do that in Qt but you also need to realize how exactly you'll be waiting on completion of workerThread. And Qt most popular way to do the interaction between threads is with signals and slots. That is why we should use QEventLoop in main. But of course there is an alternative. For lower level plain C++ you can use mutex and condition variable to accomplish the same. Or that same wait() but then there is no signals involved.
Also watch the debug output, whether or not all the connect statements really connect proper signals to slots. In case if there is no connect it prints the warning.

Deconstruct object gives QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread

My code is too long to post, here is the related part:
videoClass::videoClass()
{
...
QThread* workerThread = new QThread(this);
camwrk = new cameraWorker(workerThread);
camwrk->moveToThread(workerThread);
// There are many cross thread signal slot connections happening between this and the camwrk
}
videoClass::~videoClass()
{
...
delete camwrk;
...
}
cameraWorker::cameraWorker(QThread* workerThread)
{
_belongingThread = workerThread;
...
}
cameraWorker::cameraWorker(QThread* workerThread)
{
_belongingThread = workerThread;
...
}
cameraWorker::~cameraWorker()
{
_belongingThread->quit();
_belongingThread->wait();
}
Everytime when the _belongingThread->wait(); is finished, I got the message:
QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread
What is happening here? I thought this is the correct way to use a QThread and finish it?
The QThread object itself belongs to the main thread:
It is important to remember that a QThread instance lives in the old thread that instantiated it, not in the new thread that calls run().
Apparently, QThread::wait() is implemented via events. Since cameraWorker itself is running on workerThread and not on videoClass's thread, you can't use it.
That being said, your current logic seems a little bit too complicated. You want to stop the thread when the cameraWorker gets destroyed, and you want to destroy the camera worker when its parent gets destroyed too:
QThread* workerThread = new QThread(this);
connect(camwrk, SIGNAL(destroyed()), workerThread, SLOT(quit()));
connect(this, SIGNAL(destroyed()), camwrk, SLOT(deleteLater()));
If you want to delete the workerThread after it's finished its execution simply connect finished() and deleteLater():
connect(workerThread, SIGNAL(finished()),
workerThread, SLOT(deleteLater()));
However, keep in mind that ~videoClass() will call the destructor of workerThread. Make sure that the thread doesn't run anymore before the object gets destroyed, or simply remove this from new QThread(this) to prevent ownership.

Wake up QThread::exec() from another thread

Consider MyThread that derives from QThread and implements it's run() routine like this
void MyThread::run() {
QThread::exec();
}
or equivalently
void MyThread::run() {
QEventLoop eventLoop(this);
eventLoop.exec();
}
In this state how does one cause the 'exec' to return by some action in another thread?
To consider the opposite case: without polling, how might one post an event from the thread back to the main thread?
Apparently signals that are emitted from a thread are handled in the same thread.
You seem to have some misunderstanding how QThreads are supposed to work. Unfortunately, you are not alone with this.
The first thing to do is to read about the correct usage in here:
How To Really, Truly Use QThreads; The Full Explanation
So, what you should write is something like this:
QThread* thread1 = new QThread;
QThread* thread2 = new QThread;
Task1* task1 = new Task1();
task1->moveToThread(thread1);
Task2* task2 = new Task2();
task2->moveToThread(thread2);
connect(task2, SIGNAL(finished()), thread1, SLOT(quit()));
connect(thread2, SIGNAL(started()), task2, SLOT(process()));
thread1->start();
thread2->start();
As you can see, I am using the quit() slot just like the aforementioned example. You will need to use then emit finished() in your task2 which tries to terminate thread1 or vice versa.
QEventLoop has a slot quit that you can call. If you put a reference to the eventloop in your mythread, you can then use that to call the slot.
Signals/slots can be used in a cross thread fashion. More information here: Signals and Slots Across Threads
QMetaObject::invokeMethod( eventloop, "quit", Qt::QueuedConnection)

qt thread with movetothread

I'm trying to create a program using threads:
the main start with a loop.
When a test returns true, I create an object and I want that object to work in an other thread
then return and start the test .
QCoreApplication a(argc, argv);
while(true){
Cmd cmd;
cmd =db->select(cmd);
if(cmd.isNull()){
sleep(2);
continue ;
}
QThread *thread = new QThread( );
process *class= new process ();
class->moveToThread(thread);
thread->start();
qDebug() << " msg"; // this doesn't run until class finish it's work
}
return a.exec();
the problem is when i start the new thread the main thread stops and wait for the new thread's finish .
The canonical Qt way would look like this:
QThread* thread = new QThread( );
Task* task = new Task();
// move the task object to the thread BEFORE connecting any signal/slots
task->moveToThread(thread);
connect(thread, SIGNAL(started()), task, SLOT(doWork()));
connect(task, SIGNAL(workFinished()), thread, SLOT(quit()));
// automatically delete thread and task object when work is done:
connect(task, SIGNAL(workFinished()), task, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
in case you arent familiar with signals/slots, the Task class would look something like this:
class Task : public QObject
{
Q_OBJECT
public:
Task();
~Task();
public slots:
// doWork must emit workFinished when it is done.
void doWork();
signals:
void workFinished();
};
I don't know how you structured your process class, but this is not really the way that moveToThread works. The moveToThread function tells QT that any slots need to be executed in the new thread rather than in the thread they were signaled from. (edit: Actually, I now remember it defaults to the tread the object was created in)
Also, if you do the work in your process class from the constructor it will not run in the new thread either.
The simplest way to have your process class execute in a new thread is to derive it from QThread and override the run method. Then you never need to call move to thread at all.