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. Infinite wait when stopping QThread event loop and then calling wait
Forum Updated to NodeBB v4.3 + New Features

Infinite wait when stopping QThread event loop and then calling wait

Scheduled Pinned Locked Moved Unsolved General and Desktop
30 Posts 5 Posters 3.7k 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.
  • E Offline
    E Offline
    embeddedmz_2
    wrote on last edited by
    #11

    @J-Hilk said in Infinite wait when stopping QThread event loop and then calling wait:

    It will quit, once it gets control again and instead of processing the event queue it will quit the execution.

    but after startStressTest finished its work (and that's what happened when I clicked on the stop button), the event loop should have stopped but it didn't.

    I'll repeat what I said in one of the previous messages: if you don't click on the stop button and let the slot finish its execution and after that you call quit and wait, there is no problem.

    I think that the call to dispatcher->processEvents(QEventLoop::AllEvents) restarts the event loop and therefore cancels the effect of the quit() call.

    Please, build and play with the example I provided you. Don't ignore the informations I have posted in my replies, look at the call stacks of the stress test thread for god's sake ! Thank you.

    Christian EhrlicherC 1 Reply Last reply
    0
    • E Offline
      E Offline
      embeddedmz_2
      wrote on last edited by embeddedmz_2
      #12

      To prove you I'm right, update MainWindow::stopStressTest and StressTestManager::startStressTest with this new code :

      void MainWindow::stopStressTest()
      {
          if (m_stressTestThread == nullptr || m_stressTestManager == nullptr)
          {
              return;
          }
      
          /*QMetaObject::invokeMethod(m_stressTestManager, "setKeepStressTesting",
              Qt::QueuedConnection, Q_ARG(bool, false));*/
          m_stressTestManager->setKeepStressTesting(false);
      
          m_stressTestThread->quit(); // QT bug : doesn't work since wait() will wait indefinitely
          m_stressTestThread->wait();
      
          delete m_stressTestManager; m_stressTestManager = nullptr;
          delete m_stressTestThread; m_stressTestThread = nullptr;
      
          m_isStressTesting = false;
      
          QMessageBox::warning(this, "Application", "Stress test aborted !");
      }
      
      void StressTestManager::startStressTest()
      {
          for (size_t test = 0; test < 100 && /*!testError &&*/ /*!isCanceled()*/ m_Internals->KeepStressTesting; ++test)
          {
              QThread::msleep(100);
          }
      
          //processEvents();
      
          emit stressTestCompleted();
      }
      

      Now, there's no freeze because I don't call processEvents anymore on the dispatcher, try to uncomment isCanceled or processEvents and you will reproduce the bug.

      1 Reply Last reply
      0
      • E Offline
        E Offline
        embeddedmz_2
        wrote on last edited by embeddedmz_2
        #13

        There's also something strange I have noticed with this code :

        QObject::connect(m_canBusThread, &QThread::finished,
                             m_canBusManager, &CanBusManager::stop);
        
        m_canBusManager->moveToThread(m_canBusThread);
            m_canBusThread->start();
        

        the CanBusManager::stop will be executed in the thread managed by m_canBusThread but in the documentation this is what it says about the QThread::finished signal : When this signal is emitted, the event loop has already stopped running. But it's not true, you can check by yourself : put a breakpoint on the slot and check the thread/callstack : it is executed on the thread so the event loop is still running (or maybe something has restarted it. IDK someone needs to look to the source code).

        1 Reply Last reply
        0
        • E embeddedmz_2

          @J-Hilk said in Infinite wait when stopping QThread event loop and then calling wait:

          It will quit, once it gets control again and instead of processing the event queue it will quit the execution.

          but after startStressTest finished its work (and that's what happened when I clicked on the stop button), the event loop should have stopped but it didn't.

          I'll repeat what I said in one of the previous messages: if you don't click on the stop button and let the slot finish its execution and after that you call quit and wait, there is no problem.

          I think that the call to dispatcher->processEvents(QEventLoop::AllEvents) restarts the event loop and therefore cancels the effect of the quit() call.

          Please, build and play with the example I provided you. Don't ignore the informations I have posted in my replies, look at the call stacks of the stress test thread for god's sake ! Thank you.

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

          @embeddedmz_2 said in Infinite wait when stopping QThread event loop and then calling wait:

          but after startStressTest finished its work (and that's what happened when I clicked on the stop button), the event loop should have stopped but it didn't.

          Again: you don't run an event loop you just call processEvents() now and then. Simplify your code so we can reproduce it.

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

          E 1 Reply Last reply
          0
          • Christian EhrlicherC Christian Ehrlicher

            @embeddedmz_2 said in Infinite wait when stopping QThread event loop and then calling wait:

            but after startStressTest finished its work (and that's what happened when I clicked on the stop button), the event loop should have stopped but it didn't.

            Again: you don't run an event loop you just call processEvents() now and then. Simplify your code so we can reproduce it.

            E Offline
            E Offline
            embeddedmz_2
            wrote on last edited by embeddedmz_2
            #15

            @Christian-Ehrlicher I have posted an example here : https://github.com/embeddedmz/QTableViewAdjustPolicyNotWorkingProperly what's the problem ? If you don't take the time to read my answers completely, we can't move forward !

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

              Your example works fine for me. Add a debug output to StressTestManager::setKeepStressTesting() to see if you get there.

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

              E 1 Reply Last reply
              0
              • E Offline
                E Offline
                embeddedmz_2
                wrote on last edited by
                #17

                The solution I found for now, is to call quit() at the end of the slot so that the main thread won't wait undefinitely. It is clearly a Qt bug (the QThread::finished signal is another one, see above).

                QThread::currentThread()->quit();
                
                1 Reply Last reply
                0
                • Christian EhrlicherC Christian Ehrlicher

                  Your example works fine for me. Add a debug output to StressTestManager::setKeepStressTesting() to see if you get there.

                  E Offline
                  E Offline
                  embeddedmz_2
                  wrote on last edited by embeddedmz_2
                  #18

                  @Christian-Ehrlicher What operating system did you use ?

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

                    It works fine for me by accident since it's a timing issue in your code.
                    You got the signal to stop the thread and handle it in setKeepStressTesting(). But before this is done, QThread::quit() was called and all active eventloops were notified about it and exited. But then you call processEvents() again and start the eventloop again.
                    Use QThread::interrupt() and QThread::isInterruptionRequested() since this sets an internal QThread variable which prevents the restart of the eventloop handling.

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

                    E J.HilkJ 3 Replies Last reply
                    2
                    • Christian EhrlicherC Christian Ehrlicher

                      It works fine for me by accident since it's a timing issue in your code.
                      You got the signal to stop the thread and handle it in setKeepStressTesting(). But before this is done, QThread::quit() was called and all active eventloops were notified about it and exited. But then you call processEvents() again and start the eventloop again.
                      Use QThread::interrupt() and QThread::isInterruptionRequested() since this sets an internal QThread variable which prevents the restart of the eventloop handling.

                      E Offline
                      E Offline
                      embeddedmz_2
                      wrote on last edited by embeddedmz_2
                      #20

                      @Christian-Ehrlicher I built the example on Ubuntu 20.04 LTS and there's absolutely no problem.

                      Comment out the line that invokes setKeepStressTesting, let the main thread call quit and wait on the QThread object, wait for the stress test thread to finish running gracefully and unlike on Windows 10, the wait() will return and everything is alright (no freeze).

                      I will file a bug report since the behavior is not the same on both platforms. The Windows port clearly has a problem.

                      As for the problem with the QThread::finished signal, the documentation is incorrect. The behavior is the same on both Windows and Ubuntu : the slot of the object belonging to a QThread is executed on the thread manged by that QThread. So the event loop is still running after that signal is fired (or maybe it is restarted and then shut properly since I don't see the thread in the list when I pause the program after the execution of the slot).

                      1 Reply Last reply
                      0
                      • E Offline
                        E Offline
                        embeddedmz_2
                        wrote on last edited by embeddedmz_2
                        #21

                        @Christian-Ehrlicher On Windows 10, I built the example using Qt Creator (based on 5.15.2, the installer does not propose a more recent version, strange) and like on Ubuntu version there's absolutely no problem at all : the event loop is stopped when quit() is called and will never EVER be started again.

                        What's wrong with the vcpkg version ??!!???? You will note that my github example was originally made for an UI bug with QTableView that manifests only with vcpkg on Windows 10 (but on Windows 8.1 it's the opposite: under Qt Creator there is a problem while with vcpkg there is no problem).

                        Is vcpkg not using the right configuration to build Qt ? or is the problem only related to 5.15.3 (which I don't think) ? this kind of problem is very annoying. I don't want to stop using vcpkg since I prefer using Visual Studio instead of Qt Creator (on Windows of course).

                        1 Reply Last reply
                        0
                        • Christian EhrlicherC Christian Ehrlicher

                          It works fine for me by accident since it's a timing issue in your code.
                          You got the signal to stop the thread and handle it in setKeepStressTesting(). But before this is done, QThread::quit() was called and all active eventloops were notified about it and exited. But then you call processEvents() again and start the eventloop again.
                          Use QThread::interrupt() and QThread::isInterruptionRequested() since this sets an internal QThread variable which prevents the restart of the eventloop handling.

                          E Offline
                          E Offline
                          embeddedmz_2
                          wrote on last edited by embeddedmz_2
                          #22

                          @Christian-Ehrlicher You know what's really strange ? I uninstalled Qt (with Qt5.15.2) and reintstalled it (with Qt5.15.2 and Qt6) and now I have the issue now on Qt Creator AND the UI bug (extra white space in the QTableView) that didn't exist before the reinstallation. WTF is going on with Qt on the Windows platform ???!!?? Huge palm face ! Epic fail reward !

                          qt5.15.2_regression.png

                          1 Reply Last reply
                          0
                          • Christian EhrlicherC Christian Ehrlicher

                            It works fine for me by accident since it's a timing issue in your code.
                            You got the signal to stop the thread and handle it in setKeepStressTesting(). But before this is done, QThread::quit() was called and all active eventloops were notified about it and exited. But then you call processEvents() again and start the eventloop again.
                            Use QThread::interrupt() and QThread::isInterruptionRequested() since this sets an internal QThread variable which prevents the restart of the eventloop handling.

                            J.HilkJ Online
                            J.HilkJ Online
                            J.Hilk
                            Moderators
                            wrote on last edited by
                            #23

                            @embeddedmz_2 let me quote Christian from earlier

                            @Christian-Ehrlicher said in Infinite wait when stopping QThread event loop and then calling wait:

                            It works fine for me by accident, since it's a timing issue in your code.


                            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                            Q: What's that?
                            A: It's blue light.
                            Q: What does it do?
                            A: It turns blue.

                            E 1 Reply Last reply
                            0
                            • J.HilkJ J.Hilk

                              @embeddedmz_2 let me quote Christian from earlier

                              @Christian-Ehrlicher said in Infinite wait when stopping QThread event loop and then calling wait:

                              It works fine for me by accident, since it's a timing issue in your code.

                              E Offline
                              E Offline
                              embeddedmz_2
                              wrote on last edited by embeddedmz_2
                              #24

                              @J-Hilk I don't think it's a timing issue since there's a for loop running on the stress test thread and with each iteration process events is called on the thread's dispatcher many times after quit() has been called on the QThread object.

                              and what surprises me is what I described in my previous post about reinstalling Qt on Windows and the return of the problem with the native environment (+ the UI bug). There's a serious quality problem of the Qt version on Windows.

                              1 Reply Last reply
                              0
                              • E Offline
                                E Offline
                                embeddedmz_2
                                wrote on last edited by embeddedmz_2
                                #25

                                @Christian-Ehrlicher @J-Hilk
                                On Windows :
                                5.15.2 (MSVC2019) => bug on the QTableView and on the event loop
                                5.15.1 (MSVC2019) => bug on the QTableView and on the event loop
                                5.15.0 (MSVC2019) => bug on the QTableView and on the event loop
                                5.12.11 (MSVC2017) => everything is fine !

                                There's clearly a code regression that happened between 5.12.11 (MSVC2017) and 5.15.0 (MSVC2019).

                                I like Qt, that's why I put some effort in understanding these strange bugs.

                                5.12.11 (MSVC2017) : QTableWidget is rendered correctly + the event loop isn't restarted when processEvents is called :
                                05f8c322-ec24-4ffe-8ae1-f776d9ee807c-image.png

                                1 Reply Last reply
                                0
                                • E Offline
                                  E Offline
                                  embeddedmz_2
                                  wrote on last edited by
                                  #26

                                  bug reported here : https://bugreports.qt.io/browse/QTBUG-105207

                                  J.HilkJ 1 Reply Last reply
                                  1
                                  • E embeddedmz_2

                                    bug reported here : https://bugreports.qt.io/browse/QTBUG-105207

                                    J.HilkJ Online
                                    J.HilkJ Online
                                    J.Hilk
                                    Moderators
                                    wrote on last edited by
                                    #27

                                    @embeddedmz_2 seems like you found a bug, and not necessarily in Qt. But the culprit, like so often, is the manual call to processEvents.


                                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                    Q: What's that?
                                    A: It's blue light.
                                    Q: What does it do?
                                    A: It turns blue.

                                    E 1 Reply Last reply
                                    1
                                    • J.HilkJ J.Hilk

                                      @embeddedmz_2 seems like you found a bug, and not necessarily in Qt. But the culprit, like so often, is the manual call to processEvents.

                                      E Offline
                                      E Offline
                                      embeddedmz_2
                                      wrote on last edited by embeddedmz_2
                                      #28

                                      @J-Hilk said in Infinite wait when stopping QThread event loop and then calling wait:

                                      seems like you found a bug, and not necessarily in Qt. But the culprit, like so often, is the manual call to processEvents.

                                      if your program behaves differently from one version of Qt to another, it is a bug in Qt.

                                      JonBJ jsulmJ 2 Replies Last reply
                                      0
                                      • E embeddedmz_2

                                        @J-Hilk said in Infinite wait when stopping QThread event loop and then calling wait:

                                        seems like you found a bug, and not necessarily in Qt. But the culprit, like so often, is the manual call to processEvents.

                                        if your program behaves differently from one version of Qt to another, it is a bug in Qt.

                                        JonBJ Online
                                        JonBJ Online
                                        JonB
                                        wrote on last edited by
                                        #29

                                        @embeddedmz_2
                                        Or, it is that you relied on certain behaviour you found in a previous version, or a different platform, and decided that was guaranteed behaviour, when it is not.

                                        I read the response from the Qt devs to your bug report. It seems to me that you are in such a situation.

                                        Wouldn't it be more constructive for you to revisit how you are using processEvents() to find a better way to achieve what you want, rather than announcing what is wrong in different Qt versions/platforms? Since they say they won't change behaviour for your case that would seem more practical to me.

                                        1 Reply Last reply
                                        1
                                        • E embeddedmz_2

                                          @J-Hilk said in Infinite wait when stopping QThread event loop and then calling wait:

                                          seems like you found a bug, and not necessarily in Qt. But the culprit, like so often, is the manual call to processEvents.

                                          if your program behaves differently from one version of Qt to another, it is a bug in Qt.

                                          jsulmJ Offline
                                          jsulmJ Offline
                                          jsulm
                                          Lifetime Qt Champion
                                          wrote on last edited by
                                          #30

                                          @embeddedmz_2 said in Infinite wait when stopping QThread event loop and then calling wait:

                                          if your program behaves differently from one version of Qt to another, it is a bug in Qt.

                                          Not necesserily...

                                          https://forum.qt.io/topic/113070/qt-code-of-conduct

                                          1 Reply Last reply
                                          0

                                          • Login

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