[Qt-interest] Can I use QWaitCondition this way? How could it work reliably?
ammo
ammonite99 at googlemail.com
Wed Nov 9 17:34:19 CET 2011
Hi all,
so what i want to to was:
1. a socket only receives messages from his partner.
2. this socket works in a thread
3. the partner closes the connection (hence the thread in which the
socket works) by sending of two bytes "BR"
I did't want to use waitForReadyRead, so i tried with QWaitCondition.
first of all, if the partner requests the connection, i create a
socket in an overridden function of incomingConnection from
QTcpServer, just like this:
*************************************************************************************************
QTcpSocket* socket = new QTcpSocket;
if (!socket->setSocketDescriptor(desc)) return;
Worker* worker = new Worker(socket, this);
connect(socket, SIGNAL(readyRead()), worker, SLOT(data_available()));
connect(socket, SIGNAL(disconnected()), worker, SLOT(c_disc()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
worker->start();
*************************************************************************************************
the class Worker ist the thread where the socket works. and this class
seems like this:
*******************************beginning of
worker.h*******************************************************
class Worker: public QThread
{
Q_OBJECT
public:
Worker(QTcpSocket* socket, QObject* parent = 0);
virtual ~Worker();
void run();
private:
QTcpSocket* socket;
QMutex mutex;
QWaitCondition cond;
bool quit_ready;
public slots:
void data_available();
void c_disc();
};
*******************************end of
worker.h*******************************************************
so, the ideal is, the thread Work tries to wait on the wait condition
(the partner is sending something or the connection is closed), so the
implemetation as follows:
*******************************beginning of
worker.h*******************************************************
Worker::Worker(QTcpSocket* socket, QObject* parent)
{
quit_ready = false;
this->socket = socket;
}
Worker::~Worker()
{
mutex.lock();
quit_ready = true;
cond.wakeOne();
mutex.unlock();
wait();
if (socket) delete socket;
}
void Worker::data_available()
{
QMutexLocker locker(&mutex);
cond.wakeOne();
}
void Worker::c_disc()
{
QMutexLocker locker(&mutex);
quit_ready = true;
cond.wakeOne();
}
void Worker::run()
{
bool should_quit;
bool should_read;
QDataStream in(socket);
in.setVersion(QDataStream::Qt_4_0);
for (;;) {
should_read = socket->bytesAvailable();
mutex.lock();
should_quit = quit_ready;
if (!should_quit && !should_read) {
cond.wait(&mutex, 12000);
}
should_quit = quit_ready;
mutex.unlock();
should_read = socket->bytesAvailable();
if (!should_quit && !should_read) { qDebug() << "exit0"; goto out; }
while (socket->bytesAvailable() > 0) {
QByteArray ba;
while (ba.size() < 3) {
quint8 ch;
if (!socket->bytesAvailable() &&
!socket->waitForReadyRead(2000)) { qDebug() << "error1"; goto out; }
in >> ch;
ba.append(ch);
}
qint64 b_size = ( //first of all to get the size of message sent by
partner, 3 bytes.
(quint8(ba.at(0)) << 16) |
(quint8(ba.at(1)) << 8) |
(quint8(ba.at(2))));
QByteArray msg;
while (msg.size() < b_size) {
quint8 ch;
if (!socket->bytesAvailable() &&
!socket->waitForReadyRead(2000)) { qDebug() << "error2"; goto out; }
in >> ch;
msg.append(ch);
}
if (msg == QString("BR")) {
goto out;
}
}
if (should_quit) goto out;
}
out:
qDebug() << "out";
}
*******************************end of
worker.cpp*******************************************************
So the result is, the class Worker works fine, mostly. but sometimes i
get an error:
Qt has caught an exception thrown from an event handler. Throwing
exceptions from an event handler is not supported in Qt. You must
reimplement QApplication::notify() and catch all exceptions there.
Could someone help me, i could understand what goes wrong here. this
error happens very rarely, but it really happens. I've tried to find
out the reason since a week...thus many thanks if someone knows how
can i do this correctly.
Henning
More information about the Qt-interest-old
mailing list