PDA

View Full Version : QTimer fires timeout after stop()



Willi
27th January 2014, 22:16
I use QT 5.2 and have the following code:


#ifndef HANDLELOCALMESSAGE_H
#define HANDLELOCALMESSAGE_H

#include <QByteArray>
#include <QList>
#include <QTcpSocket>
#include <QTimer>
#include "handlemessage.h"

class HandleLocalMessage : public HandleMessage
{
Q_OBJECT
public:
explicit HandleLocalMessage(IniFile* i, QObject *parent = 0);
virtual ~HandleLocalMessage();

public slots:

private:
virtual void endProcess();
void writeList();
void errorHandling();

QTcpSocket socket;
QByteArray transArray;
QTimer toTimer;
bool conn;

private slots:
virtual void processMessage();
void connected();
void error(QAbstractSocket::SocketError socketError);
void timeout();
void readyRead();
void checkEnd();

signals:
void stopTimer();
};

#endif // HANDLELOCALMESSAGE_H



#include <QDebug>
#include <QSystemSemaphore>
#include <QThread>
#include "handlelocalmessage.h"

HandleLocalMessage::HandleLocalMessage(IniFile* i, QObject *parent) :
HandleMessage(i, parent),
socket(this),
toTimer(this),
conn(false) {

interval = 30000;
toTimer.setSingleShot(true);
toTimer.setInterval(ini->integer("GLOBALSERVER","TIMEOUT",5)*1000);
connect(&socket , SIGNAL(connected()) , this, SLOT(connected()) );
connect(&socket , SIGNAL(readyRead()) , this, SLOT(readyRead()) );
connect(&socket , SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError)) );
connect(&socket , SIGNAL(disconnected()) , this, SLOT(checkEnd()) );
connect(&toTimer, SIGNAL(timeout()) , this, SLOT(timeout()) );
connect(this , SIGNAL(stopTimer()) , &toTimer, SLOT(stop()) );
}

HandleLocalMessage::~HandleLocalMessage() {

}


void HandleLocalMessage:: processMessage() {
socket.connectToHost("host", 5000, QIODevice::ReadWrite);
toTimer.start();
} else {
endProcess();
}
}

void HandleLocalMessage::endProcess() {

emit log(LogFile:: Debug,"HandleLocalMessage: endProcess: End Process called");
if (toend) {
...
} else {
timer->start();
}
}


void HandleLocalMessage::writeList() {

....
}


void HandleLocalMessage::errorHandling() {

....
}


void HandleLocalMessage::connected() {

conn = true;
socket.write(transArray+"### End of Message ###");
}

void HandleLocalMessage::error(QAbstractSocket::SocketE rror socketError) {

// Q_UNUSED(socketError);
emit log(LogFile:: Debug,"Error during communication with global server: "+QString().setNum(socketError));
toTimer.stop();
emit log(LogFile:: Debug,"Timeout-Timer with Id "+QString().setNum(toTimer.timerId())+" active after stop: "+QString(toTimer.isActive() ? "YES" : "NO"));
errorHandling();
socket.close();
socket.disconnectFromHost();
}

void HandleLocalMessage::timeout() {

emit log(LogFile:: Debug,"Timeout during communication with global server. Timeout-Timer Id: "+QString().setNum(toTimer.timerId()));
errorHandling();
socket.close();
if (conn) {
socket.disconnectFromHost();
} else {
checkEnd();
}
}

void HandleLocalMessage::readyRead() {

toTimer.stop();
QByteArray res(socket.readAll());
if (!(res == QByteArray("OK"))) {
errorHandling();
}
socket.close();
socket.disconnectFromHost();
}



void HandleLocalMessage::checkEnd() {

endProcess();
}


I deleted some parts wich has nothing to do with the timer.

The Problem is the QTimer toTimer. The Connection to the QTcpServer is not wrking and normaly the timeout is fired. All fine. But sometimes the connect Ends with the error-condition. Than I try to stop the timer with "toTimer.stop()". The Logmesage identifies it as inactive. But the timeout is fired anyway.

Any idea why? To be honest: I have no idea and I'm stuck.

Thx in advance and regards

sulliwk06
27th January 2014, 22:41
Can you be sure nothing else is starting the timer again after you log it as inactive? Maybe after you've stopped the timer you could check back every couple of seconds to see if it is still inactive?

ChrisW67
28th January 2014, 05:54
A function called endProcess() can start the timer again if toend is false. Nothing in your code indicates what this variable might be or gives it a value.

Willi
28th January 2014, 12:09
Thx for the suggestions. The not shown part of the code was guaranteed to not influence the timer. But sulliwk06 showed the correct way. I logged the Status of the timer every 200 milliseconds and saw that the Status was sometimes exact the opposite way it was supposed to be. The Problem was this Piece of code:


void HandleLocalMessage:: processMessage() {
socket.connectToHost("host", 5000, QIODevice::ReadWrite);
toTimer.start();
} else {
endProcess();
}
}


I have to start the toTimer before the connect() because the error-condition Comes up too fast so that the error-Routine (and therefore the stop()) was executed before the start().