Results 1 to 5 of 5

Thread: Using QApplication::processEvents - possible hang under linux

  1. #1
    Join Date
    Jan 2014
    Posts
    3
    Qt products
    Qt4 Qt5

    Unhappy Using QApplication::processEvents - possible hang under linux

    Hi all, This is my first post in this forum so I hope it will help.

    I have written a Qt based (4.8.3) GUI client that is used to configure a remote network switch. The GUI consists of a main thread that processes all the UI and a worker thread used to communicate with the server. All communication with the server is done using a bespoke API that in turn uses an RPC type protocol to communicate with the remote server. All API calls return an error code

    So for example the client (GUI) may issue the following command

    err = initializePhyPort(0)

    The InitialisePhyPort API call is spawned from the main thread via a button press for example and is queued for execution by the worker thread which communicates with the server. Once the worker thread has executed the command the results are passed back to the main thread so that the GUI can be updated. here is the code for a API spawn operation:

    The pre-processor constant WORKER_THREAD enables or disables the use of the worker thread

    Qt Code:
    1. altr_ret_status_e api_operation_manager_t::add_new_and_wait(const api_data_t api_data)
    2. {
    3. m_mutex.lock();
    4.  
    5. m_api_op = new api_operation_t(api_data, false, false);
    6. m_flush = false;
    7.  
    8. m_operations_pnd.push_back(m_api_op);
    9.  
    10. m_mutex.unlock();
    11.  
    12. backhaul_gui::set_wait_cursor();
    13. backhaul_gui::set_status_busy();
    14.  
    15. altr_ret_status_e err = ALTR_RET_SUCCESS;
    16.  
    17. m_wait_op_busy = true;
    18.  
    19. #ifndef WORKER_THREAD
    20.  
    21. // This can take some time!!
    22. run();
    23.  
    24. #endif
    25.  
    26. // Wait for the operation to complete - Note this may spawn further 'silent' ops
    27. // Note that it is possible for the client to disconnect during this loop. In which case flush will be called
    28. while(m_api_op->status() < OP_STATE_DONE)
    29. {
    30. Sleep(1);
    31.  
    32. QApplication::processEvents();
    33. }
    34.  
    35. // Process any pending events (usually a MSG_BOX_EVENT_TYPE)
    36. if (m_api_op->m_event)
    37. {
    38. QCoreApplication::postEvent(g_gui, m_api_op->m_event);
    39. }
    40.  
    41. err = m_api_op->m_err;
    42.  
    43. // Remove anything in the done queue
    44. m_mutex.lock();
    45.  
    46. for (api_vec_t::iterator it = m_operations_done.begin(); it != m_operations_done.end(); ++it)
    47. {
    48. delete *it;
    49. }
    50.  
    51. m_operations_done.clear();
    52.  
    53. m_api_op = &m_default_op;
    54.  
    55. m_mutex.unlock();
    56.  
    57. // Signal that we are done
    58. op_completed();
    59.  
    60. m_wait_op_busy = false;
    61.  
    62. return err;
    63. }
    To copy to clipboard, switch view to plain text mode 

    So (in multi-threaded mode) the main thread will wait in a loop calling processEvents until the worker thread has done its thing. It will then return the error code. My problem is that under Linux I am seeing, very occasionaly, X-Server errors and I am almost certain, but not 100%, that the cause is due to the processEvents loop. When I run in single thread mode I do not see any X-Server errors.

    Sorry for the somewhat long initial thread.

    SJ
    Last edited by SpanishJohn; 6th January 2014 at 15:10.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Using QApplication::processEvents - possible hang under linux

    Calling sleep is never a good idea in the main thread.

    You can use a nested event loop to do event processing while "waiting" for something, e.g. a signal from the thread.

    Way better, however, would be to always process the second half in a slot and emit the signal from either the thread or the code that is run when there is no thread.

    Cheers,
    _

  3. #3
    Join Date
    Jan 2014
    Posts
    3
    Qt products
    Qt4 Qt5

    Default SOLVED Re: Using QApplication::processEvents - possible hang under linux

    Lesson learned. Be *very* careful when using QApplication ProcessEvents as it can hang on systems with signal recursion link Linux/X11.

    Here is my new code that uses a QEventLoop

    Qt Code:
    1. altr_ret_status_e api_operation_manager_t::wait_done(void)
    2. {
    3. altr_ret_status_e err = ALTR_RET_SUCCESS;
    4.  
    5. // Assert if we spawn another wait operation in the while loop below
    6. check(m_wait_op_busy == false);
    7.  
    8. m_wait_op_busy = true;
    9.  
    10. #ifndef WORKER_THREAD
    11.  
    12. // This may take some time!!
    13. run();
    14.  
    15. #endif
    16.  
    17. // Wait for the operation to complete - Note this may spawn further 'silent' ops
    18. // Note that it is possible for the client to disconnect during this loop. In which case flush will be called
    19. m_event_loop.exec();
    20.  
    21. if (m_flush)
    22. {
    23. // The client has been disconnected *or* the application wants to close
    24. err = ALTR_RET_CLIENT_CLOSED;
    25.  
    26. if (!api_layer_t::active())
    27. {
    28. // The application wants to close
    29. THROW_EXCEPTION_TRAP
    30. }
    31. }
    32. else
    33. {
    34. // Process any pending events (usually a MSG_BOX_EVENT_TYPE)
    35. if (m_api_op->m_event)
    36. {
    37. QCoreApplication::postEvent(g_gui, m_api_op->m_event);
    38. }
    39.  
    40. err = m_api_op->m_err;
    41.  
    42. {
    43. MUTEX_LOCKER locker(&m_mutex);
    44.  
    45. // Remove anything in the done queue
    46. for (api_vec_t::iterator it = m_operations_done.begin(); it != m_operations_done.end(); ++it)
    47. {
    48. delete *it;
    49. }
    50.  
    51. m_operations_done.clear();
    52.  
    53. m_api_op = &m_default_op;
    54. }
    55.  
    56. // Signal that we are done
    57. op_completed();
    58. }
    59.  
    60. m_wait_op_busy = false;
    61.  
    62. return err;
    63. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: SOLVED Re: Using QApplication::processEvents - possible hang under linux

    Couldn't you also move the eventLoop.exec into an #else case of the ifdef?
    I.e. if you call run() directly, do you still need to wait for something?

    Cheers,
    _

  5. #5
    Join Date
    Jan 2014
    Posts
    3
    Qt products
    Qt4 Qt5

    Default Re: Using QApplication::processEvents - possible hang under linux

    Hi, If the worker thread is enabled then run() *is* the worker thread. The worker thread executes the queued commands and for each command the main thread will wait via the QEventLoop exec(). If the worker thread is disabled, then run() must be called explicitly, but the QEventLoop is still necessary as each command requires a GUI update phase (signalled from run()). At the end of the GUI update phase the QEventLoop quit() method is called.

    Anyway, most importantly, the use of the QEventLoop has solved my X11 problems that I experienced using QApplication ProcessEvents

    Regards, SJ
    Last edited by SpanishJohn; 9th January 2014 at 11:48.

Similar Threads

  1. Replies: 6
    Last Post: 18th January 2012, 20:21
  2. BlockingQueuedConnection hang
    By ^NyAw^ in forum Qt Programming
    Replies: 7
    Last Post: 17th February 2010, 18:30
  3. QApplication::setLibraryPaths doesn't work under Linux
    By NoRulez in forum Qt Programming
    Replies: 1
    Last Post: 10th January 2010, 19:51
  4. QCop - QApplication::ProcessEvents()
    By QbelcorT in forum Qt for Embedded and Mobile
    Replies: 5
    Last Post: 1st March 2009, 15:58
  5. Problems with QApplication::processEvents()
    By Winni in forum Qt Programming
    Replies: 15
    Last Post: 5th January 2008, 19:31

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.