Hello,
I have a main thread (GUI) and a worker thread. From the main thread I'm calling a function in the worker thread that waits for a event to be posted on the worker thread's own queue. But it looks like the event is processed only after the main thread gets control back.

Here is a complete test class (test.h) that reproduces the problem. As soon as it is created, the worker thread starts a 5 seconds timer. When you click the button in the main widget, it waits for the timer event to be triggered.

Qt Code:
  1. #include <QThread>
  2. #include <QTimer>
  3. #include <QWaitCondition>
  4. #include <QMutex>
  5. #include <QPushButton>
  6. #include <QVBoxLayout>
  7. #include <QMessageBox>
  8.  
  9. //
  10. // Worker
  11. //
  12. class Worker: public QThread
  13. {
  14. Q_OBJECT
  15. public:
  16. Worker(): tmrNotifyWhenDone(this)
  17. {
  18. // start 5 seconds timer
  19. tmrNotifyWhenDone.setInterval(5000);
  20. connect(&tmrNotifyWhenDone, SIGNAL(timeout()), this, SLOT(onWorkCompleted()));
  21. tmrNotifyWhenDone.start();
  22.  
  23. // enter thread event loop
  24. start();
  25. }
  26.  
  27. bool waitForWorkCompleted() // called from the main thread, see below
  28. {
  29. mutex.lock();
  30. bool ok = workCompleted.wait(&mutex, 6000);
  31. mutex.unlock();
  32.  
  33. return ok;
  34. }
  35.  
  36. private slots:
  37. void onWorkCompleted()
  38. // this is called only when the message box is shown... WHY?
  39. {
  40. workCompleted.wakeAll();
  41. }
  42.  
  43. private:
  44. QTimer tmrNotifyWhenDone;
  45. QMutex mutex;
  46. QWaitCondition workCompleted;
  47. };
  48.  
  49.  
  50. //
  51. // MainWidget
  52. //
  53. class MainWidget : public QWidget
  54. {
  55. Q_OBJECT
  56. public:
  57. MainWidget(QWidget* parent = 0): QWidget(parent)
  58. {
  59. QPushButton* btnWaitWorkCompleted = new QPushButton("Wait for work completed");
  60. connect(btnWaitWorkCompleted, SIGNAL(clicked()), this, SLOT(onBtnWaitWorkCompleted()));
  61.  
  62. QVBoxLayout* layout = new QVBoxLayout();
  63. layout->addWidget(btnWaitWorkCompleted);
  64. setLayout(layout);
  65. }
  66.  
  67. private slots:
  68. void onBtnWaitWorkCompleted()
  69. {
  70. if (worker.waitForWorkCompleted())
  71. QMessageBox::information(0, "Test", "Ok!");
  72. else
  73. QMessageBox::information(0, "Test", "Wrong!");
  74. }
  75.  
  76. private:
  77. Worker worker;
  78. };
To copy to clipboard, switch view to plain text mode