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. Strange signal handling (nested eventloops)
Forum Updated to NodeBB v4.3 + New Features

Strange signal handling (nested eventloops)

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 3 Posters 984 Views 1 Watching
  • 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.
  • ocgltdO Offline
    ocgltdO Offline
    ocgltd
    wrote on last edited by ocgltd
    #1

    (Working with Qt 5.15.2)
    I have a method which receives a signal (sig_responseReady) from the same thread. The purpose of this method is to wait until a response is received. While this method is waiting for the signal, the method is called again because of an event which calls this method (so eventloops get nested). However, the first waitForResponse on the stack does not get the signal for up to 10 seconds (for no reason I can see), while later called waitForResponse get their signal first.

    The result of this design is that I have nested eventloops, which according to this stackoverflow post causes slot/signal handling errors, and should be avoided. I suspect this is the cause of my problem.

    Is there a design which accomplishes the same, with only a single eventloop? (I can't come up with it) The function which calls waitForResponse must pause until waitForResponse returns. ..I can't make it asynchronous. I tried replacing eventloop.exec with QCoreApplication::processEvents(QEventLoop::AllEvents,100), but still get same strange result. (So maybe nested event loops is not the problem...but I can't figure out the cause)

    MyClass::SRequest MyClass::waitForResponse(const QUuid queryID) {
    
        reentryCount++;  // Static var to determing nesting/depth count
        QEventLoop eventloop;
        qDebug() << "MyClass::waitForResponse connect for uid " << queryID << ", depth " << reentryCount;
        connect(this,&MyClass::sig_responseReady,&eventloop, &QEventLoop::quit); //, Qt::QueuedConnection);  // Allow matching response to stop eventloop
        do {
            eventloop.exec();
            qDebug() << "MyClass::waitForResponse got signal for uid " << queryID;
        } while (!queryResponseReady(queryID) && !queryExpired(queryID));
        qDebug() << "MyClass::waitForResponse exitted loop for signal for uid " << queryID << ", depth " << reentryCount;
    
        reentryCount--;
        return queryTakeResult(queryID);
    }
    
    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @ocgltd said in Strange signal handling (nested eventloops):

      The purpose of this method is to wait until a response is received.

      This is wrong. Don't do this - use Signals and Slots.
      Calling QEventLoop is strongly discouraged because of the problems you see above (and others - e.g. another signal can kill your object inside the newly created eventloop) - fix your design.

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

      1 Reply Last reply
      2
      • ocgltdO Offline
        ocgltdO Offline
        ocgltd
        wrote on last edited by ocgltd
        #3

        This code (MyClass) is part of a descendant of QAbstractItemModel. MyClass retrieves data from a DB (eg rowcount) from another thread by sending a request signal, and then receiving a response signal.

        So in my overriden rowCount method I must keep an eventloop running to receive the incoming response signal, but wait there until receiving an answer - so it must process events That's the purpose of waitForResponse method). But this allows a second rowCount method to be called in the same thread, so I get overlapping waitForResponse's running.

        This is clearly a design problem...but I can't figure out a solution. Any recommendation on the right way to design this? (so I don't have overlapping eventloops)

        Christian EhrlicherC 1 Reply Last reply
        0
        • ocgltdO ocgltd

          This code (MyClass) is part of a descendant of QAbstractItemModel. MyClass retrieves data from a DB (eg rowcount) from another thread by sending a request signal, and then receiving a response signal.

          So in my overriden rowCount method I must keep an eventloop running to receive the incoming response signal, but wait there until receiving an answer - so it must process events That's the purpose of waitForResponse method). But this allows a second rowCount method to be called in the same thread, so I get overlapping waitForResponse's running.

          This is clearly a design problem...but I can't figure out a solution. Any recommendation on the right way to design this? (so I don't have overlapping eventloops)

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

          @ocgltd said in Strange signal handling (nested eventloops):

          So in my overriden rowCount method I must keep an eventloop running to receive the incoming response signal, but wait there until receiving an answer

          No, this can and will not work. You really must not create an eventloop inside rowCount().
          Pass your data from the db thread to the main thread via signals and slots and properly call begin/endInsertRows() there.

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

          ocgltdO 1 Reply Last reply
          2
          • Christian EhrlicherC Christian Ehrlicher

            @ocgltd said in Strange signal handling (nested eventloops):

            So in my overriden rowCount method I must keep an eventloop running to receive the incoming response signal, but wait there until receiving an answer

            No, this can and will not work. You really must not create an eventloop inside rowCount().
            Pass your data from the db thread to the main thread via signals and slots and properly call begin/endInsertRows() there.

            ocgltdO Offline
            ocgltdO Offline
            ocgltd
            wrote on last edited by
            #5

            @Christian-Ehrlicher I think you are suggesting that I create a descendant of QAbstractItemModel model. And since each of the functions that must be overridden (eg: rowCount, data) must return information immediately, I must return some form of dummy data that later gets replaced with real data when my DB thread returns answers?

            ...I'm new to QAbstractItemModel so trying to wrap my head around how to make it asynchronous..

            Christian EhrlicherC 1 Reply Last reply
            0
            • ocgltdO ocgltd

              @Christian-Ehrlicher I think you are suggesting that I create a descendant of QAbstractItemModel model. And since each of the functions that must be overridden (eg: rowCount, data) must return information immediately, I must return some form of dummy data that later gets replaced with real data when my DB thread returns answers?

              ...I'm new to QAbstractItemModel so trying to wrap my head around how to make it asynchronous..

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

              @ocgltd said in Strange signal handling (nested eventloops):

              that I create a descendant of QAbstractItemModel model.

              You for sure have to derive from QAbstractItemModel -how else will you return the data otherwise?

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

              ocgltdO 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                @ocgltd said in Strange signal handling (nested eventloops):

                that I create a descendant of QAbstractItemModel model.

                You for sure have to derive from QAbstractItemModel -how else will you return the data otherwise?

                ocgltdO Offline
                ocgltdO Offline
                ocgltd
                wrote on last edited by
                #7

                @Christian-Ehrlicher Yes I phrased that poorly :)

                In order to make QAbstractItemModel asynchronous, I think I will have to create a caching mechanism. The overridden functions (like rowCount, data) will have to return fake results immediately with some type of indicator that data is not cached, and once the real data arrives from the DB thread I will have to emit a data changed signal for that parent/row/col.

                Seems like something that someone would have already done...

                Christian EhrlicherC 1 Reply Last reply
                0
                • ocgltdO ocgltd

                  @Christian-Ehrlicher Yes I phrased that poorly :)

                  In order to make QAbstractItemModel asynchronous, I think I will have to create a caching mechanism. The overridden functions (like rowCount, data) will have to return fake results immediately with some type of indicator that data is not cached, and once the real data arrives from the DB thread I will have to emit a data changed signal for that parent/row/col.

                  Seems like something that someone would have already done...

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

                  @ocgltd said in Strange signal handling (nested eventloops):

                  will have to return fake results

                  No, no fake results. It simply returns the rows which are already known. No need to fake anything.

                  btw: What should a db thread do when you wait for it in the gui thread anyway?

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

                  ocgltdO 1 Reply Last reply
                  1
                  • Christian EhrlicherC Christian Ehrlicher

                    @ocgltd said in Strange signal handling (nested eventloops):

                    will have to return fake results

                    No, no fake results. It simply returns the rows which are already known. No need to fake anything.

                    btw: What should a db thread do when you wait for it in the gui thread anyway?

                    ocgltdO Offline
                    ocgltdO Offline
                    ocgltd
                    wrote on last edited by
                    #9

                    @Christian-Ehrlicher The DB thread will be waiting for the SQL transactions to complete (on a very slow DB)

                    jsulmJ 1 Reply Last reply
                    0
                    • ocgltdO ocgltd

                      @Christian-Ehrlicher The DB thread will be waiting for the SQL transactions to complete (on a very slow DB)

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

                      @ocgltd The point from @Christian-Ehrlicher is that you're waiting in main thread for the db thread to complete, so there is no point to have a thread at all.

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

                      ocgltdO 1 Reply Last reply
                      0
                      • jsulmJ jsulm

                        @ocgltd The point from @Christian-Ehrlicher is that you're waiting in main thread for the db thread to complete, so there is no point to have a thread at all.

                        ocgltdO Offline
                        ocgltdO Offline
                        ocgltd
                        wrote on last edited by
                        #11

                        @jsulm I have multiple threads doing other (unrelated) DB activities. Since the db connection cannot be shared between threads I had to move to a single thread.

                        jsulmJ 1 Reply Last reply
                        0
                        • ocgltdO ocgltd

                          @jsulm I have multiple threads doing other (unrelated) DB activities. Since the db connection cannot be shared between threads I had to move to a single thread.

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

                          @ocgltd said in Strange signal handling (nested eventloops):

                          Since the db connection cannot be shared between threads

                          Each thread can have its own db connection

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

                          1 Reply Last reply
                          2

                          • Login

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