Results 1 to 18 of 18

Thread: Non-Gui thread blocking gui

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Aug 2006
    Posts
    163
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    12
    Thanked 5 Times in 4 Posts

    Default Non-Gui thread blocking gui

    The following code is a slot. When calling it using a signal from an object running in the GUI thread, the GUI blocks until the slot is finished executing. Which is a bit strange, because this code is running in it's own thread, so it shouldn't do that, right?
    Also, it blocks until timeWaited == timeout*1000 (10 seconds in this case ) which it shouldn't, because the moment the thread connects to the server it changes the state of st into CONNECTED or LOGGED_IN. So obviously something is going wrong, but since this is my first time ever using threads I'm a bit lost.

    Qt Code:
    1. void Connection::deferredWriteCommand( const QString& command )
    2. {
    3. if( !isRunning() ){
    4. start();
    5. }
    6. bool done = false;
    7. int timeWaited = 0;
    8. while( !done && timeWaited < timeout*1000 ){
    9. switch( st ){
    10. case DISCONNECTED:
    11. wait( 1000 );
    12. timeWaited += 1000;
    13. break;
    14. case CONNECTED:
    15. if( parent->getAuthorization() ){
    16. wait( 1000 );
    17. timeWaited += 1000;
    18. }else{
    19. socket->write( command.toLatin1(), (quint64) command.length() );
    20. socket->flush();
    21. done = true;
    22. }
    23. break;
    24. case LOGGED_IN:
    25. socket->write( command.toLatin1(), (quint64) command.length() );
    26. socket->flush();
    27. done = true;
    28. break;
    29. default:
    30. break;
    31. };
    32. if( done ){
    33. break;
    34. }
    35. }
    36. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Non-Gui thread blocking gui

    What is this Connection class? Subclass of QThread? If so, then you're doing a strange thing here:
    Qt Code:
    1. if( !isRunning() ){
    2. start();
    3. }
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Aug 2006
    Posts
    163
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    12
    Thanked 5 Times in 4 Posts

    Default Re: Non-Gui thread blocking gui

    Yes, it's a sublass of QThread. You're not allowed to run it from itself? Well, that never gets called anyway, since the code that starts the thread is called from another class, and looks like this :

    Qt Code:
    1. if( !server.at( index )->connection( i )->isRunning() ){
    2. server.at( index )->connection( i )->start( QThread::NormalPriority );
    3. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Non-Gui thread blocking gui

    Quote Originally Posted by Valheru View Post
    You're not allowed to run it from itself?
    It's not that you're not allowed. It just doesn't make sense to do so, because to trigger a slot, you need an event loop running, so if you run the loop from within a slot, the loop must be already running, because the slot was triggered.

    In your case there are two possibilities - either the block occurs because you did something in the main thread or the slot is called in the context of the main thread (instead of the worker thread) which obviously blocks its event loop. Are you sure the slot is run from the worker thread? Could you show us the connect statement for that slot?

  5. #5
    Join Date
    Aug 2006
    Posts
    163
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    12
    Thanked 5 Times in 4 Posts

    Default Re: Non-Gui thread blocking gui

    Qt Code:
    1. void Server::fetchGroups()
    2. {
    3. //emit emitLogData( "fetchGroups() called" );
    4. bool done = false;
    5. for( int i = 0; i < getNumberConnections(); i++ ){
    6. switch( connections.at( i )->state() ){
    7. case Connection::CONNECTED:
    8. //emit emitLogData( QString( "Connection %1 state = CONNECTED" ).arg( i ) );
    9. disconnect( this, SIGNAL( emitDeferredWriteCommand( const QString& ) ) );
    10. connect( this, SIGNAL( emitDeferredWriteCommand( const QString& ) ),
    11. connections.at( i ), SLOT( deferredWriteCommand( const QString& ) ) );
    12. emit emitDeferredWriteCommand( "LIST\r\n" );
    13. done = true;
    14. break;
    15. case Connection::DISCONNECTED:
    16. //emit emitLogData( QString( "Connection %1 state = DISCONNECTED" ).arg( i ) );
    17. addServerTab();
    18. connections.at( i )->start( QThread::NormalPriority );
    19. disconnect( this, SIGNAL( emitDeferredWriteCommand( const QString& ) ) );
    20. connect( this, SIGNAL( emitDeferredWriteCommand( const QString& ) ),
    21. connections.at( i ), SLOT( deferredWriteCommand( const QString& ) ) );
    22. emit emitDeferredWriteCommand( "LIST\r\n" );
    23. done = true;
    24. break;
    25. case Connection::LOGGED_IN:
    26. //emit emitLogData( QString( "Connection %1 state = LOGGED_IN" ).arg( i ) );
    27. connections.at( i )->writeCommand("LIST\r\n");
    28. done = true;
    29. break;
    30. case Connection::LISTING_GROUPS:
    31. break;
    32. default:
    33. emit emitLogData("No available connections" );
    34. break;
    35. };
    36. if( done ){
    37. //emit emitLogData( QString( "Connection %1 found" ).arg( i ) );
    38. break;
    39. }
    40. }
    41. }
    To copy to clipboard, switch view to plain text mode 

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Non-Gui thread blocking gui

    Hmm... very strange... Why don't you use custom events instead of such a complicated and strange design?

    Qt Code:
    1. const int MyCustomEventNum = QEvent::User+1;
    2. class MyCustomEvent : public QEvent {
    3. MyCustomEvent(const QString &comm) : QEvent(MyCustomEventNum){
    4. _comm = comm;
    5. }
    6. const QString &command() const { return _comm; }
    7. private:
    8. QString _comm;
    9. };
    10. void Connection::customEvent(QEvent *e){
    11. if(e->type()==MyCustomEventNum){
    12. doSomething(((MyCustomEvent*)e)->command());
    13. }
    14. }
    To copy to clipboard, switch view to plain text mode 
    and in your code:
    Qt Code:
    1. case Connection::CONNECTED:
    2. QCoreApplication::postEvent(connections.at( i ), new MyCustomEvent("LIST\r\n"));
    3. break;
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    Aug 2006
    Posts
    163
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    12
    Thanked 5 Times in 4 Posts

    Default Re: Non-Gui thread blocking gui

    Well, the reason for this is because the user could concievably call fetchGroups() before connecting to the server. In this case, the first available Connection should connect to the server before issuing the command to the NNTP server. This is why I created a slot in the Connection class that does just that. What is confusing me is that although every Connection runs in it's own thread, and doesn't block the GUI while it's doing other things, it does block the GUI when doing this one thing.

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Non-Gui thread blocking gui

    You could try explicitely calling connect with the additional parameter Qt::QueuedConnection, but I still think using custom events would be simpler, quicker and nicer.

  9. #9
    Join Date
    Aug 2006
    Posts
    163
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    12
    Thanked 5 Times in 4 Posts

    Default Re: Non-Gui thread blocking gui

    Heh, I just tried it as a queuedconnection and you're right - it didn't help I've just been looking at the docs for the custom event, I didn't even know that they existed - thanks for the tip. I'll try that now.

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Non-Gui thread blocking gui

    It may behave incorrectly because you are emitting the signal to the thread object. And the thread object lives in the same thread as the calling object (only objects created within run() or from within methods called from the thread's event loop live in the worker thread), so the slot might be called by the wrong (main) thread. It could be possible that all you need to do is to wait until the thread is started before emitting the signal (but you have to explicitely use queued connections for that to work!) - that would explain why subsequent signals work correctly.

    Qt Code:
    1. connections.at( i )->start( QThread::NormalPriority );
    2. while(!connections.at(i)->isRunning()) QThread::sleep(100); //crude, but should work
    To copy to clipboard, switch view to plain text mode 

  11. #11
    Join Date
    Aug 2006
    Posts
    163
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    12
    Thanked 5 Times in 4 Posts

    Default Re: Non-Gui thread blocking gui

    Would the custom event run in the worker thread? I'd prefer to do it that way if it is so, I'm busy restructuring the program now to make it cleaner and fix bugs so I don't want to hack some half-assed fix in if at all possible

Similar Threads

  1. simple thread layout question
    By mhoover in forum Qt Programming
    Replies: 1
    Last Post: 12th August 2006, 11:02
  2. Replies: 11
    Last Post: 7th July 2006, 13:09
  3. [QT4] QThread and printing a QList<QPixmap>
    By KShots in forum Qt Programming
    Replies: 3
    Last Post: 24th April 2006, 21:44
  4. Problem building Qt4.1.0 with thread support on windows XP
    By pavithra in forum Installation and Deployment
    Replies: 1
    Last Post: 1st April 2006, 11:35
  5. Replies: 2
    Last Post: 6th January 2006, 21:15

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
  •  
Qt is a trademark of The Qt Company.