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. How am I blocking the event loop
QtWS25 Last Chance

How am I blocking the event loop

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 6 Posters 900 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.
  • ocgltdO Offline
    ocgltdO Offline
    ocgltd
    wrote on last edited by ocgltd
    #1

    I have written a class that handles a TCP socket connection. I also have a timer (X seconds) that alerts me if a response has not been received in X time over the socket.

    When I call a method that sends a message over the socket, the characters go out, and a response comes back almost instantaneous, BUT....my readyRead slot does not run. However, it does run once the above timer expires. It's as if the event loop lost the data received signal...or was blocked some how. But once the timeout signal fires then the readyRead slot runs right after.

    Out of interest, I tried calling that same function as a slot (using emit). Then everything works perfectly, and the readyRead signal fires as soon as data is actually received.

    Why is this happening (conceptually - no need to ask for code)?? What can cause a signal to get lost, or what could block the event loop (yet an identical method call using emit works fine). I don't use QThreads....pretty simple

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

      @ocgltd well, yes and probably

      As long as you're inside a slot, no other remaining (queued up) events will be processed.

      Also if your event processing takes forever, new events won't appended to the currently "todo" list,

      new events will be queued up and processed when the event loop is run next

      also if you try to write to the socket from the ready read slot that can lead to event loop blocks. I think thats explicitly stated in the documentation?


      Edit: only found this in my quick search

      readyRead() is not emitted recursively; if you reenter the event loop or call waitForReadyRead() inside a slot connected to the readyRead() signal, the signal will not be reemitted (although waitForReadyRead() may still return true).
      
      ocgltdO Offline
      ocgltdO Offline
      ocgltd
      wrote on last edited by ocgltd
      #12

      Ok solved it! I found a couple things including a poorly designed loop (per SGaist) and also sending to the QTcpSocket while in the readyRead slot (leading to receiving data while in the slot) (per JHilk).

      The problem was intermittent, but running with Valgrind slowed everything down enough that I was able to confirm the cause(s). Now working properly....

      Thanks for the feedback, and interesting discussion on how the slots are handled.

      JonBJ 1 Reply Last reply
      1
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Hi,

        Got any while loop running ?

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        ocgltdO 1 Reply Last reply
        0
        • SGaistS SGaist

          Hi,

          Got any while loop running ?

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

          @SGaist I do have quite a few, but why would they run (indefinitely/in a way that blocks)...but only if I call the method directly instead of using emit?

          I can narrow down my investigate of while loops if I could understand how this could happen

          JonBJ 1 Reply Last reply
          0
          • ocgltdO ocgltd

            I have written a class that handles a TCP socket connection. I also have a timer (X seconds) that alerts me if a response has not been received in X time over the socket.

            When I call a method that sends a message over the socket, the characters go out, and a response comes back almost instantaneous, BUT....my readyRead slot does not run. However, it does run once the above timer expires. It's as if the event loop lost the data received signal...or was blocked some how. But once the timeout signal fires then the readyRead slot runs right after.

            Out of interest, I tried calling that same function as a slot (using emit). Then everything works perfectly, and the readyRead signal fires as soon as data is actually received.

            Why is this happening (conceptually - no need to ask for code)?? What can cause a signal to get lost, or what could block the event loop (yet an identical method call using emit works fine). I don't use QThreads....pretty simple

            C Offline
            C Offline
            ChrisW67
            wrote on last edited by
            #4

            @ocgltd said in How am I blocking the event loop:

            Why is this happening (conceptually - no need to ask for code)??

            Then no expectation of addressing your particular problem.

            What can cause a signal to get lost,

            Not connecting it, or connecting the wrong object, would be the top contenders.

            If there are no user threads involved then if the signal is emitted everything connected to it will be executed before the "emit" signal returns. If something in a connected slot causes it it to never return then the program will become non-responsive. If something in a slot is triggering more (the original) signals in a circular arrangement then this might also never return.

            ocgltdO 1 Reply Last reply
            0
            • ocgltdO ocgltd

              @SGaist I do have quite a few, but why would they run (indefinitely/in a way that blocks)...but only if I call the method directly instead of using emit?

              I can narrow down my investigate of while loops if I could understand how this could happen

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #5

              @ocgltd said in How am I blocking the event loop:

              but only if I call the method directly instead of using emit?

              You realize that emit signal() is identical to just writing signal(), don't you? emit is #defined to empty. If that's what you meant.

              ocgltdO 1 Reply Last reply
              0
              • JonBJ JonB

                @ocgltd said in How am I blocking the event loop:

                but only if I call the method directly instead of using emit?

                You realize that emit signal() is identical to just writing signal(), don't you? emit is #defined to empty. If that's what you meant.

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

                @JonB I have the connection setup as Qt::QueuedConnection, so it's more than just a simple call. It uses the eventloop to call my method.

                But...I had a thought.

                I send data (and receive data) over the TCP socket while I'm in the QTimer timeout slot. Does Qt implement slot processing in such a way that if a new signal arrives while a slot is running (or signals are being processed), that new signal will only be processed next time the eventloop detects idle or receives a NEW signal?

                That would explain my symptom.

                C jsulmJ JonBJ J.HilkJ 4 Replies Last reply
                0
                • C ChrisW67

                  @ocgltd said in How am I blocking the event loop:

                  Why is this happening (conceptually - no need to ask for code)??

                  Then no expectation of addressing your particular problem.

                  What can cause a signal to get lost,

                  Not connecting it, or connecting the wrong object, would be the top contenders.

                  If there are no user threads involved then if the signal is emitted everything connected to it will be executed before the "emit" signal returns. If something in a connected slot causes it it to never return then the program will become non-responsive. If something in a slot is triggering more (the original) signals in a circular arrangement then this might also never return.

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

                  @ChrisW67 Based on the above I don't think an incorrect connection is the cause.

                  But generating a signal while running a slot is interesting....see my note below.

                  1 Reply Last reply
                  0
                  • ocgltdO ocgltd

                    @JonB I have the connection setup as Qt::QueuedConnection, so it's more than just a simple call. It uses the eventloop to call my method.

                    But...I had a thought.

                    I send data (and receive data) over the TCP socket while I'm in the QTimer timeout slot. Does Qt implement slot processing in such a way that if a new signal arrives while a slot is running (or signals are being processed), that new signal will only be processed next time the eventloop detects idle or receives a NEW signal?

                    That would explain my symptom.

                    C Offline
                    C Offline
                    ChrisW67
                    wrote on last edited by
                    #8

                    @ocgltd said in How am I blocking the event loop:

                    I send data (and receive data) over the TCP socket while I'm in the QTimer timeout slot.

                    This is non-blocking unless you deliberately use blocking QAbstractSocket::waitFor... methods.

                    1 Reply Last reply
                    0
                    • ocgltdO ocgltd

                      @JonB I have the connection setup as Qt::QueuedConnection, so it's more than just a simple call. It uses the eventloop to call my method.

                      But...I had a thought.

                      I send data (and receive data) over the TCP socket while I'm in the QTimer timeout slot. Does Qt implement slot processing in such a way that if a new signal arrives while a slot is running (or signals are being processed), that new signal will only be processed next time the eventloop detects idle or receives a NEW signal?

                      That would explain my symptom.

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

                      @ocgltd said in How am I blocking the event loop:

                      I have the connection setup as Qt::QueuedConnection, so it's more than just a simple call

                      What @JonB means is that "emit" is an empty macro. So "emit signal();" is EXACTLY the same as "signal();".

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

                      1 Reply Last reply
                      1
                      • ocgltdO ocgltd

                        @JonB I have the connection setup as Qt::QueuedConnection, so it's more than just a simple call. It uses the eventloop to call my method.

                        But...I had a thought.

                        I send data (and receive data) over the TCP socket while I'm in the QTimer timeout slot. Does Qt implement slot processing in such a way that if a new signal arrives while a slot is running (or signals are being processed), that new signal will only be processed next time the eventloop detects idle or receives a NEW signal?

                        That would explain my symptom.

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by
                        #10

                        @ocgltd said in How am I blocking the event loop:

                        @JonB I have the connection setup as Qt::QueuedConnection, so it's more than just a simple call. It uses the eventloop to call my method.

                        As @jsulm has said on my behalf :), I was talking about emit signal() being identical to signal(), no more and no less. In your case, either one would queue the signal.

                        Does Qt implement slot processing in such a way that if a new signal arrives while a slot is running (or signals are being processed), that new signal will only be processed next time the event loop detects idle or receives a NEW signal?

                        For, say, a queued connection signals are only processed (slots called) when the event loop is next hit.

                        An interesting one would be if the first signal has a queued connection and the new signal a direct connection. In this case I imagine the new signal would be processed immediately, before the previous queued connection was started or even in the middle of it being processed/its slots executing. The default (at least where no threads involved) direct connection effectively means that slots are called directly from the [emit] signal() statement, just as though it directly called each slot in turn before continuing to the next statement. So far as I know, the fact that, say, a signal/slot (queued or not) is currently in progress would not be taken into account or alter this behaviour.

                        1 Reply Last reply
                        0
                        • ocgltdO ocgltd

                          @JonB I have the connection setup as Qt::QueuedConnection, so it's more than just a simple call. It uses the eventloop to call my method.

                          But...I had a thought.

                          I send data (and receive data) over the TCP socket while I'm in the QTimer timeout slot. Does Qt implement slot processing in such a way that if a new signal arrives while a slot is running (or signals are being processed), that new signal will only be processed next time the eventloop detects idle or receives a NEW signal?

                          That would explain my symptom.

                          J.HilkJ Offline
                          J.HilkJ Offline
                          J.Hilk
                          Moderators
                          wrote on last edited by J.Hilk
                          #11

                          @ocgltd well, yes and probably

                          As long as you're inside a slot, no other remaining (queued up) events will be processed.

                          Also if your event processing takes forever, new events won't appended to the currently "todo" list,

                          new events will be queued up and processed when the event loop is run next

                          also if you try to write to the socket from the ready read slot that can lead to event loop blocks. I think thats explicitly stated in the documentation?


                          Edit: only found this in my quick search

                          readyRead() is not emitted recursively; if you reenter the event loop or call waitForReadyRead() inside a slot connected to the readyRead() signal, the signal will not be reemitted (although waitForReadyRead() may still return true).
                          

                          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.

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

                            @ocgltd well, yes and probably

                            As long as you're inside a slot, no other remaining (queued up) events will be processed.

                            Also if your event processing takes forever, new events won't appended to the currently "todo" list,

                            new events will be queued up and processed when the event loop is run next

                            also if you try to write to the socket from the ready read slot that can lead to event loop blocks. I think thats explicitly stated in the documentation?


                            Edit: only found this in my quick search

                            readyRead() is not emitted recursively; if you reenter the event loop or call waitForReadyRead() inside a slot connected to the readyRead() signal, the signal will not be reemitted (although waitForReadyRead() may still return true).
                            
                            ocgltdO Offline
                            ocgltdO Offline
                            ocgltd
                            wrote on last edited by ocgltd
                            #12

                            Ok solved it! I found a couple things including a poorly designed loop (per SGaist) and also sending to the QTcpSocket while in the readyRead slot (leading to receiving data while in the slot) (per JHilk).

                            The problem was intermittent, but running with Valgrind slowed everything down enough that I was able to confirm the cause(s). Now working properly....

                            Thanks for the feedback, and interesting discussion on how the slots are handled.

                            JonBJ 1 Reply Last reply
                            1
                            • ocgltdO ocgltd has marked this topic as solved on
                            • ocgltdO ocgltd

                              Ok solved it! I found a couple things including a poorly designed loop (per SGaist) and also sending to the QTcpSocket while in the readyRead slot (leading to receiving data while in the slot) (per JHilk).

                              The problem was intermittent, but running with Valgrind slowed everything down enough that I was able to confirm the cause(s). Now working properly....

                              Thanks for the feedback, and interesting discussion on how the slots are handled.

                              JonBJ Offline
                              JonBJ Offline
                              JonB
                              wrote on last edited by
                              #13

                              @ocgltd said in How am I blocking the event loop:

                              but running with Valgrind slowed everything down enough

                              An excellent use of valgrind :)

                              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