QUdpSocket::readyRead() doesn't emit after thread event loop restart
-
wrote on 4 Mar 2011, 15:08 last edited by
Good day, colleagues!
I have one Q_OBJECT class (A) with second Q_OBJECT class (B) nested in A. B contains QUdpSocket that listens specified port and some code that process incoming UDP packets. In ctor of A I create a QThread and move B with QUdpSocket to the new thread. Then I call thread->start() and all works well - B happily receives UDP packets and process it.
After some time, I stop listening thread calling thread->quit() from A. Then, again after some time, I restart thread calling thread->start(). Thread starts successfully but readyRead() is never emitted, although UDP packets arrive to target port.
I have a full control over incoming UDP packets, so I sure that I read all UDP packets before calling thread->quit(), my problem is not caused by presence of pending datagrams at QUdpSocket.
If I don't stop and start the thread, all is OK and readyRead() signal is emitted as usual. Here is pseudocode:
@class B : public QObject {
Q_OBJECTpublic:
B (int port, QMutex * mutex);
QUdpSocket socket;
void Move_To_Thread (); // Safely move B and UDP socket to target threadprivate:
QMutex * mutex_;
void Process ();
};class A : public QObject {
Q_OBJECTpublic:
A ();
void Run();private:
B b;
QThread * thread;
QMutex mutex;
};A::A() {
thread = new QThread(this);
b.Move_To_Thread (thread);
}void A::Run () {
thread->start(); Sleep (SOME_TIME); thread->quit(); Sleep (OTHER_TIME); thread->start();
}@
-
wrote on 4 Mar 2011, 17:42 last edited by
Try to simplify the problem (I won't ask why you're doing networking in a separate thread).
How are you putting the socket in listening mode? Without/with threads involved, if packets arrive before the event loop is started (but after the socket is listening), is readyRead emitted?
-
wrote on 5 Mar 2011, 08:46 last edited by
Here are the pseudocode for putting socket in a listening mode:
@B::B (int port, QMutex * mutex) : mutex_ (mutex) {
socket.bind(port);
connect (&socket, SIGNAL(readyRead()), this, SIGNAL(Process()));
}@UDP packets start arriving only after I start event loop. So:
@void A::Run () {
thread->start(); // UDP packets start arriving, for this piece of code readyRead() emits as usual Sleep (SOME_TIME); // UDP packets stop arriving Sleep (WAIT_PACKETS_TIME); thread->quit(); Sleep (OTHER_TIME); thread->start(); // UDP packets start arriving again, but readyRead() not emitted
}@
And how can I check if the readyRead() was emitted without starting event loop?
1/3