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. QEventLoop and qWait interaction
QtWS25 Last Chance

QEventLoop and qWait interaction

Scheduled Pinned Locked Moved General and Desktop
qtestlibqeventloop
4 Posts 2 Posters 2.6k 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.
  • S Offline
    S Offline
    Svalorzen
    wrote on 10 Mar 2016, 12:04 last edited by
    #1

    I'm using a series of QEventLoops in order to concurrently wait for specific signals with specific parameters in different parts of my code without blocking the rest of the application (no gui). This is required as these signals rely the information on whether certain operations did succeed or not.

    This code looks like this:

    if ( !expectMySignals(lambdaWithTriggeringAction, signals...)
    {
        zError("Error while receiving events, aborting...");
        return end();
    }
    
    // continue...
    

    With the expectMySignals function looking like this:

    bool expectMySignals(...) 
    {
        QEventLoop loop;
        QTimer timer;
        // This keeps track of all incoming signals and emits()
        // when they all arrived.
        SignalVerifier verifier;
    
        if (!/* Bind verifier to all required signals */)
            return false;
    
        if (!QObject::connect(&verifier, SIGNAL(verified()), &loop, SLOT(quit())))
            return false;
    
        if (!QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())))
            return false;
    
        runLambdaWithTriggeringAction();
    
        // IMPORTANT:
        // We wait AT MOST 5 seconds for the signals, otherwise we abort
        timer.start(5000);
    
        loop.exec();
        return verifier.isVerified();
    }
    

    I'm using this solution in order to keep the code as streamlined as possible, without the need to split execution into numerous multiple functions called when all signals arrive.

    Everything seems to work correctly, but when writing tests for this code I have noticed that, if concurrent qWaits to this code exist and the signals do not arrive, the code after a qWait does not get executed until the timer within expectMySignals does not expire, no matter the amount of time specified within qWait. For example:

    QSignalSpy tester(/* some binding to test */);
    
    doAction();
    
    // We want to give a bit of time to the code to do its work.
    // Then it should wait for signals incoming.
    
    QTest::qWait(500);  /* <-- This blocks for some reason until
                               expectMySignals fails, no matter 
                               the number inside (be 500, 50, 1..) */
    
    triggerExpectedSignals();
    QTest::qWait(500);
    
    // We test that the code did its job.
    QVERIFY(tester.count() == 1);
    

    Why does this happen?

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 10 Mar 2016, 23:07 last edited by
      #2

      Hi and welcome to devnet,

      Your base design sounds a bit convoluted. Why not just trigger a check when you receive these signals and only start the rest once they all have been received ? Something maybe like a state machine

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

      S 1 Reply Last reply 11 Mar 2016, 12:02
      0
      • S SGaist
        10 Mar 2016, 23:07

        Hi and welcome to devnet,

        Your base design sounds a bit convoluted. Why not just trigger a check when you receive these signals and only start the rest once they all have been received ? Something maybe like a state machine

        S Offline
        S Offline
        Svalorzen
        wrote on 11 Mar 2016, 12:02 last edited by
        #3

        @SGaist Hi, thanks for the welcome. I actually did just do that, even though I like this style less (I had to do a switch with all the state machine states, and after verifying the signals I would call the same function with a different state instead of a simple if/else).

        I was actually just curious on how this worked in order to understand better how Qt works under the hood =)

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 11 Mar 2016, 20:32 last edited by
          #4

          You can find the implementation in qtestsystem.h

          It basically trigger event processing and sleeps a short time.

          Can you show a picture of how your system should work ?

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

          1 Reply Last reply
          0

          3/4

          11 Mar 2016, 12:02

          • Login

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