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
Forum Updated to NodeBB v4.3 + New Features

How am I blocking the event loop

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 6 Posters 973 Views 3 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 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