March 4, 2011

usamytch usamytch
Lab Rat
22 posts

QUdpSocket::readyRead() doesn’t emit after thread event loop restart


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:

  1. class B : public QObject {
  2.     Q_OBJECT
  4. public:
  5.     B (int port, QMutex * mutex);
  6.     QUdpSocket socket;
  7.     void Move_To_Thread (); // Safely move B and UDP socket to target thread
  9. private:
  10.     QMutex * mutex_;
  11.     void Process ();
  12. };
  14. class A : public QObject {
  15.     Q_OBJECT
  17. public:
  18.     A ();
  19.     void Run();
  21. private:
  22.     B b;
  23.     QThread * thread;
  24.     QMutex mutex;
  25. };
  27. A::A() {
  28.     thread = new QThread(this);
  29.     b.Move_To_Thread (thread);
  30. }
  32. void A::Run () {
  34.     thread->start();
  35.     Sleep (SOME_TIME);
  36.     thread->quit();
  37.     Sleep (OTHER_TIME);
  38.     thread->start();
  39. }

2 replies

March 4, 2011

peppe peppe
Ant Farmer
1005 posts

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?


Software Engineer
KDAB (UK) Ltd., a KDAB Group company

March 5, 2011

usamytch usamytch
Lab Rat
22 posts

Here are the pseudocode for putting socket in a listening mode:

  1. B::B (int port, QMutex * mutex) : mutex_ (mutex) {
  2.     socket.bind(port);
  3.     connect (&socket, SIGNAL(readyRead()), this, SIGNAL(Process()));
  4. }

UDP packets start arriving only after I start event loop. So:

  1. void A::Run () {
  3.     thread->start();
  4.     // UDP packets start arriving, for this piece of code readyRead() emits as usual
  5.     Sleep (SOME_TIME);
  6.     // UDP packets stop arriving
  7.     Sleep (WAIT_PACKETS_TIME);
  8.     thread->quit();
  10.     Sleep (OTHER_TIME);
  11.     thread->start();
  12.     // UDP packets start arriving again, but readyRead() not emitted
  13. }

And how can I check if the readyRead() was emitted without starting event loop?

  ‹‹ Bug in QTextEdit ?      [Solved] Error handling on async tree model loading ››

You must log in to post a reply. Not a member yet? Register here!