Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QIODevice::readAll hangs
QtWS25 Last Chance

QIODevice::readAll hangs

Scheduled Pinned Locked Moved Solved General and Desktop
qtcpsocketreadallinfinite loop
10 Posts 3 Posters 607 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Chruetli
    wrote on last edited by
    #1

    Hi
    (using Qt 6.5.3)
    after increasing network traffic, reading from a socket results in an infinite loop.
    I inherited the following code:

      while (threadRun) {
        while ((m_pDevice->bytesAvailable() == 0) && (threadRun)) {
          msleep(50);
        }
        if (threadRun) {
          msleep(20);
          QByteArray protoAr = m_pDevice->readAll();
          processXml(protoAr);
        } 
      } 
    

    and some else we have:

    m_pDevice = new QTcpSocket(this);
    

    Means we are reading XML content from a TCP socket (~4 messages per second, ~120 Bytes each) and processing it. I know that incomplete reads can occur but that's currently not (yet) a problem.

    After some time we notice that the task hangs in a loop and consumes 100% CPU.
    gdb shows the following backtrace:
    Screenshot 2024-05-15 093410.png

    The implementation of readAll is shown here https://codebrowser.dev/qt6/qtbase/src/corelib/io/qiodevice.cpp.html#_ZN9QIODevice7readAllEv
    from there we jump to read https://codebrowser.dev/qt6/qtbase/src/corelib/io/qiodevice.cpp.html#_ZN16QIODevicePrivate4readEPcxb and finally to QRingBuffer::read https://codebrowser.dev/qt6/qtbase/src/corelib/tools/qringbuffer.cpp.html#_ZN11QRingBuffer4readEPcx

    qint64 QRingBuffer::read(char *data, qint64 maxLength)
    {
        const qint64 bytesToRead = qMin(size(), maxLength);
        qint64 readSoFar = 0;
        while (readSoFar < bytesToRead) {
            const qint64 bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar,
                                                         nextDataBlockSize());
            if (data)
                memcpy(data + readSoFar, readPointer(), bytesToReadFromThisBlock);
            readSoFar += bytesToReadFromThisBlock;
            free(bytesToReadFromThisBlock);
        }
        return readSoFar;
    }
    

    Any idea what's going wrong?

    Thanks for helping!

    1 Reply Last reply
    0
    • C Offline
      C Offline
      Chruetli
      wrote on last edited by
      #3

      @Christian-Ehrlicher : Of course you are right, but as this is a very low level routine i was reluctant to make wide changes. Nevertheless I tried it now and surprisingly little code remains. (Still have to remove Thread from the class name)

      connect(m_pDevice.get(), &QIODevice::readyRead, this, &xmlReaderThread::readData);
      ...
      
      void xmlReaderThread::readData() {
          QByteArray protoAr = m_pDevice->readAll();
          processXml(protoAr);
      }
      

      Looks better now?

      Christian EhrlicherC 1 Reply Last reply
      0
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Even though I know the answer but: Use signals and slots (and no need for a thread at all) - all of the above is completely unneeded with Qt...

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        2
        • C Offline
          C Offline
          Chruetli
          wrote on last edited by
          #3

          @Christian-Ehrlicher : Of course you are right, but as this is a very low level routine i was reluctant to make wide changes. Nevertheless I tried it now and surprisingly little code remains. (Still have to remove Thread from the class name)

          connect(m_pDevice.get(), &QIODevice::readyRead, this, &xmlReaderThread::readData);
          ...
          
          void xmlReaderThread::readData() {
              QByteArray protoAr = m_pDevice->readAll();
              processXml(protoAr);
          }
          

          Looks better now?

          Christian EhrlicherC 1 Reply Last reply
          0
          • C Chruetli

            @Christian-Ehrlicher : Of course you are right, but as this is a very low level routine i was reluctant to make wide changes. Nevertheless I tried it now and surprisingly little code remains. (Still have to remove Thread from the class name)

            connect(m_pDevice.get(), &QIODevice::readyRead, this, &xmlReaderThread::readData);
            ...
            
            void xmlReaderThread::readData() {
                QByteArray protoAr = m_pDevice->readAll();
                processXml(protoAr);
            }
            

            Looks better now?

            Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #4

            @Chruetli said in QIODevice::readAll hangs:

            Looks better now

            Much better. But could not read out if the problem still persists. If so print out the bytesAvailable and only try to read that much bytes.

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            C 1 Reply Last reply
            0
            • Christian EhrlicherC Christian Ehrlicher

              @Chruetli said in QIODevice::readAll hangs:

              Looks better now

              Much better. But could not read out if the problem still persists. If so print out the bytesAvailable and only try to read that much bytes.

              C Offline
              C Offline
              Chruetli
              wrote on last edited by
              #5

              @Christian-Ehrlicher said in QIODevice::readAll hangs:

              Much better. But could not read out if the problem still persists. If so print out the bytesAvailable and only try to read that much bytes.

              Me neither... I need my hardware first to try it.

              Christian EhrlicherC 1 Reply Last reply
              0
              • C Chruetli

                @Christian-Ehrlicher said in QIODevice::readAll hangs:

                Much better. But could not read out if the problem still persists. If so print out the bytesAvailable and only try to read that much bytes.

                Me neither... I need my hardware first to try it.

                Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #6

                @Chruetli said in QIODevice::readAll hangs:

                I need my hardware first to try it.

                :)

                I'm not aware of a bug report wrt this problem. Was m_pDevice created in the correct thread?

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                C 1 Reply Last reply
                0
                • Christian EhrlicherC Christian Ehrlicher

                  @Chruetli said in QIODevice::readAll hangs:

                  I need my hardware first to try it.

                  :)

                  I'm not aware of a bug report wrt this problem. Was m_pDevice created in the correct thread?

                  C Offline
                  C Offline
                  Chruetli
                  wrote on last edited by Chruetli
                  #7

                  @Christian-Ehrlicher said in QIODevice::readAll hangs:

                  I'm not aware of a bug report wrt this problem. Was m_pDevice created in the correct thread?

                  Yes, at least this looks fine! Just for interest, what's the problem with this? Do you have me a pointer?

                  Btw. what's the difference between readAll() and read(bytesAvailable());?

                  Christian EhrlicherC JonBJ 2 Replies Last reply
                  0
                  • C Chruetli

                    @Christian-Ehrlicher said in QIODevice::readAll hangs:

                    I'm not aware of a bug report wrt this problem. Was m_pDevice created in the correct thread?

                    Yes, at least this looks fine! Just for interest, what's the problem with this? Do you have me a pointer?

                    Btw. what's the difference between readAll() and read(bytesAvailable());?

                    Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by
                    #8

                    @Chruetli said in QIODevice::readAll hangs:

                    Do you have me a pointer?

                    Accessing a QTcpSocket (or anything else) from different threads will not work / results in undefined behavior.

                    Btw. what's the difference between readAll() and read(bytesAvailable());?

                    Nothing in reality, just wanted to see if it makes a difference for you by any chance.

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    1 Reply Last reply
                    0
                    • C Chruetli

                      @Christian-Ehrlicher said in QIODevice::readAll hangs:

                      I'm not aware of a bug report wrt this problem. Was m_pDevice created in the correct thread?

                      Yes, at least this looks fine! Just for interest, what's the problem with this? Do you have me a pointer?

                      Btw. what's the difference between readAll() and read(bytesAvailable());?

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #9

                      @Chruetli said in QIODevice::readAll hangs:

                      Btw. what's the difference between readAll() and read(bytesAvailable());?

                      Timing, I imagine! :)

                      1 Reply Last reply
                      0
                      • C Offline
                        C Offline
                        Chruetli
                        wrote on last edited by
                        #10

                        I tested it with my hardware an now it works! Thanks for helping me out!

                        1 Reply Last reply
                        0
                        • C Chruetli has marked this topic as solved on

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved