Results 1 to 5 of 5

Thread: Program hangs up in QTcpSocket::readLine()

  1. #1
    Join Date
    Jan 2006
    Location
    Innsbruck, Austria
    Posts
    62
    Thanks
    10
    Thanked 7 Times in 6 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Program hangs up in QTcpSocket::readLine()

    I have a GUI thread and a worker thread which reads from a socket. The worker thread uses the readyRead() signal to read input from the socket, process it and emit some signals that are connected to the GUI thread using a queued connection. The problem is the application sometimes just randomly blocks. Using gdb I've found just the exact place where it blocks and it seems to be just in the Qt code, which is quite strange. I could understand the worker thread getting blocked if there was no more available data in the socket ( although that shouldn't happen since I use QTcpSocket::canReadLine() ) but the GUI is getting blocked, thus not processing events and causing the typical efects of not repainting when it's needed.

    This is the relevant code of the worker thread:

    Qt Code:
    1. void ManagerThread::run()
    2. {
    3. m_mutex.lock();
    4. QString hostName = m_hostName;
    5. quint16 port = m_port;
    6. m_mutex.unlock();
    7.  
    8. m_socket = new QTcpSocket;
    9. connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)),
    10. this, SLOT(handleConnectionError(QAbstractSocket::SocketError)));
    11.  
    12. m_socket->connectToHost(hostName, port);
    13. if (!m_socket->waitForConnected()) {
    14. delete m_socket;
    15. return;
    16. }
    17.  
    18. if(sendLogin()) {
    19. connect(m_socket, SIGNAL(readyRead()),
    20. this, SLOT(readInput()));
    21. setConnected(true);
    22. emit connected();
    23. exec();
    24. setConnected(false);
    25. }
    26.  
    27. m_socket->disconnectFromHost();
    28.  
    29. delete m_socket;
    30. }
    31.  
    32.  
    33. void ManagerThread::readInput()
    34. {
    35. bool timerStarted = false;
    36.  
    37. while(m_socket->canReadLine()) {
    38. QString line = m_socket->readLine();
    39. line.remove('\r');
    40. line.remove('\n');
    41. if(line.isEmpty()) {
    42. m_pendingCommands.append(m_currentCommand);
    43. m_currentCommand.clear();
    44.  
    45. if(!timerStarted) {
    46. QTimer::singleShot(0, this, SLOT(parsePendingCommands()));
    47. timerStarted = true;
    48. }
    49. } else
    50. m_currentCommand.append(line);
    51. }
    52. }
    To copy to clipboard, switch view to plain text mode 

    It hangs in the m_socket->readLine() call. When it hangs, I press Ctrl+C and this is the backtrace I get:

    Qt Code:
    1. (gdb) run
    2. Starting program: /home/djworld/curro/dialapplet/dialapplet/bin/dialapplet
    3. Failed to read a valid object file image from memory.
    4. [Thread debugging using libthread_db enabled]
    5. [New Thread -1224792368 (LWP 10926)]
    6. Qt: gdb: -nograb added to command-line options.
    7. Use the -dograb option to enforce grabbing.
    8. [New Thread -1228108912 (LWP 10929)]
    9. [New Thread -1236501616 (LWP 10930)]
    10. [New Thread -1248855152 (LWP 12367)]
    11.  
    12. Program received signal SIGINT, Interrupt.
    13. [Switching to Thread -1224792368 (LWP 10926)]
    14. 0xb7463b06 in QRingBuffer::readPointer (this=0x80e8694)
    15. at ../../include/QtCore/private/../../../src/corelib/tools/qringbuffer_p.h:54
    16. 54 ../../include/QtCore/private/../../../src/corelib/tools/qringbuffer_p.h:
    17. File or directory doesn't exist.
    18.  
    19. in ../../include/QtCore/private/../../../src/corelib/tools/qringbuffer_p.h
    20. (gdb) bt
    21. #0 0xb7463b06 in QRingBuffer::readPointer (this=0x80e8694)
    22. at ../../include/QtCore/private/../../../src/corelib/tools/qringbuffer_p.h:54
    23. #1 0xb7475494 in QAbstractSocket::readData (this=0x8164370,
    24. data=0x81f6418 "_madrugada\nQueue: Cola_madrugLocation:
    25. SIP/101\naMembership:Penalty: 0\n stCallsTaken: LastCall: Status: 6\nPEvent:
    26. QueueMemberStaPrivilege: aQueue: Cola\ngent,aMembership:CallsTaken:
    27. 26\ntic\nl\nStatus: 6\nP"..., maxSize=16384) at qabstractsocket.cpp:1699
    28. #2 0xb732701a in QIODevice::read (this=0x8164370, data=0xbf9e8d2a "\236�I ",
    29. maxSize=1) at io/qiodevice.cpp:768
    30. #3 0xb73183d6 in QIODevice::getChar (this=0x8164370, c=0xbf9e8d77 "\b")
    31. at ../../include/QtCore/../../src/corelib/io/qiodevice.h:116
    32. #4 0xb7327590 in QIODevice::readLineData (this=0x8164370,
    33. data=0x81d5570 "0\024Y]\001", maxSize=4063) at io/qiodevice.cpp:1112
    34. #5 0xb74751f8 in QAbstractSocket::readLineData (this=0x8164370,
    35. data=0x81d5570 "0\024Y]\001", maxlen=4063) at qabstractsocket.cpp:1719
    36. #6 0xb732689d in QIODevice::readLine (this=0x8164370, data=0x81d5550 "Event:
    37. QueueMemberStaPrivilege: 0\024Y]\001", maxSize=4095) at io/qiodevice.cpp:1013
    38. #7 0xb7326b10 in QIODevice::readLine (this=0x8164370, maxSize=0) at
    39. io/qiodevice.cpp:1081
    40. #8 0x08052e01 in ManagerThread::readInput (this=0x8141408) at
    41. managerthread.cpp:103
    42. #9 0x08073bfd in ManagerThread::qt_metacall (this=0x8141408,
    43. _c=QMetaObject::InvokeMetaMethod, _id=8, _a=0xb5900648) at
    44. moc_managerthread.cpp:95
    45. #10 0xb7399b2a in QObject::event (this=0x8141408, e=0xb5900668) at
    46. kernel/qobject.cpp:1025
    47. #11 0xb77ed7e1 in QApplicationPrivate::notify_helper (this=0x8095278,
    48. receiver=0x8141408, e=0xb5900668) at kernel/qapplication.cpp:3434
    49. #12 0xb77edada in QApplication::notify (this=0xbf9e9774, receiver=0x8141408,
    50. e=0xb5900668) at kernel/qapplication.cpp:3009
    51. #13 0xb738936b in QCoreApplication::sendEvent (receiver=0x8141408,
    52. event=0xb5900668) at kernel/qcoreapplication.h:183
    53. #14 0xb7386ce0 in QCoreApplication::sendPostedEvents (receiver=0x0,
    54. event_type=0) at kernel/qcoreapplication.cpp:1021
    55. #15 0xb7888f20 in QCoreApplication::sendPostedEvents ()
    56. at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:188
    57. #16 0xb788837e in QEventDispatcherX11::processEvents (this=0x809ca00,
    58. flags=@0xbf9e95ac) at kernel/qeventdispatcher_x11.cpp:55
    59. #17 0xb7383f06 in QEventLoop::processEvents (this=0xbf9e963c,
    60. flags=@0xbf9e95f0) at kernel/qeventloop.cpp:126
    61. #18 0xb7384089 in QEventLoop::exec (this=0xbf9e963c, flags=@0xbf9e9644) at
    62. kernel/qeventloop.cpp:172
    63. #19 0xb73875b0 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:727
    64. #20 0xb77ed364 in QApplication::exec () at kernel/qapplication.cpp:2927
    65. #21 0x0806138c in main (argc=Cannot access memory at address 0x0
    66. ) at main.cpp:50
    To copy to clipboard, switch view to plain text mode 

    Any idea? I'm using Qt 4.2.2 on openSUSE 10.2.
    Last edited by vfernandez; 20th February 2007 at 20:16. Reason: typed a wrong version number

  2. #2
    Join Date
    Jan 2006
    Location
    Norway
    Posts
    124
    Thanked 38 Times in 30 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Program hangs up in QTcpSocket::readLine()

    Are you able to reproduce this reliably? If so, can you please post a complete example that reproduces it?

    Off the top of my head, it might look like the slot you're invoking in your QThread subclass is run from the thread that created it, rather than the thread that runs run(). Tongue-in-cheek, try creating a QTcpSocket subclass that handles its own readyReads, instead of declaring the slot in the thread class. ;-)
    Last edited by Bitto; 20th February 2007 at 20:35.
    Bitto / Andreas Aardal Hanssen - andreas dot aardal dot hanssen at nokia
    Nokia Software Manager, Qt Development

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Program hangs up in QTcpSocket::readLine()

    Try:
    Qt Code:
    1. connect( m_socket, SIGNAL( readyRead() ), this, SLOT( readInput() ), Qt::DirectConnection );
    To copy to clipboard, switch view to plain text mode 
    Otherwise readInput() will be invoked by the GUI thread (as "this" lives in the GUI thread and you create a queued connection).

  4. The following user says thank you to jacek for this useful post:

    vfernandez (21st February 2007)

  5. #4
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Program hangs up in QTcpSocket::readLine()

    "This" aka ManagerThread lives in the thread it was created. Mark the connections explicitly as direct to get the slots executed in the same thread than what's being executed in ManagetThread::run():
    Qt Code:
    1. connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)),
    2. this, SLOT(handleConnectionError(QAbstractSocket::SocketError)), Qt::DirectConnection);
    3. ...
    4. connect(m_socket, SIGNAL(readyRead()), this, SLOT(readInput()), Qt::DirectConnection);
    To copy to clipboard, switch view to plain text mode 
    J-P Nurmi

  6. The following user says thank you to jpn for this useful post:

    vfernandez (21st February 2007)

  7. #5
    Join Date
    Jan 2006
    Location
    Innsbruck, Austria
    Posts
    62
    Thanks
    10
    Thanked 7 Times in 6 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Program hangs up in QTcpSocket::readLine()

    Thanks! That was exactly the problem. I would never have thought the readInput() function was being run in the gui thread but I've inserted qDebug() << QThread::currentThread(); in it and damn! that was happening. It would be nice if the Qt documentation warned about this thing. IMHO, it's a bit confusing at this point.

Similar Threads

  1. QT Program debug,GDB on Linux
    By darpan in forum General Programming
    Replies: 1
    Last Post: 26th January 2007, 22:02
  2. QT MySQL
    By sabeeshcs in forum Newbie
    Replies: 6
    Last Post: 12th January 2007, 04:19
  3. Release my simple program to other users ?
    By probine in forum Qt Programming
    Replies: 9
    Last Post: 9th July 2006, 23:42
  4. preparing program for release
    By impeteperry in forum Installation and Deployment
    Replies: 5
    Last Post: 22nd April 2006, 19:30
  5. Enter key causing program to exit
    By welby in forum Qt Programming
    Replies: 2
    Last Post: 9th March 2006, 16:11

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.