Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. General talk
  3. Brainstorm
  4. QEventLoop + QNetworkRequest = dead lock

QEventLoop + QNetworkRequest = dead lock

Scheduled Pinned Locked Moved Solved Brainstorm
7 Posts 3 Posters 931 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.
  • A Offline
    A Offline
    acetone
    wrote on last edited by acetone
    #1

    In Qt6, I've found that the bundle identified in the topic title sometimes has a dead lock. I have never noticed this before.

    QNetworkRequest request(url);
    auto reply = networkManager.post(request, multiPart);
    
    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();
    

    Pure classic combination for some REST API requests.

    As it turned out, in some scenarios reply does not emit the QNetworkReply::finished signal and the thread hangs forever.

    I found a not-so-pretty but workable solution:

    #define REQUEST_DEADLOCK_SAVER \
    QTimer timer;\
        timer.setSingleShot(true);\
        timer.setInterval(REQUEST_TIMEOUT);\
        QObject::connect(&timer, &QTimer::timeout, [&loop](){\
                qWarning() << "Network request dropped by timeout";\
                loop.quit();\
        });\
        QObject::connect(reply, &QNetworkReply::finished, &timer, &QTimer::stop);\
        timer.start();
    

    Use it like this:

    QNetworkRequest request(url);
    auto reply = networkManager.post(request, multiPart) : this->aManager.get(request);
    
    QEventLoop loop;
    REQUEST_DEADLOCK_SAVER // <-------- solution
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();
    

    Has anyone encountered a similar problem?

    JonBJ jeremy_kJ 2 Replies Last reply
    0
    • A Offline
      A Offline
      acetone
      wrote on last edited by
      #7

      So I simply needed handle one more signal:

      QObject::connect(reply, &QNetworkReply::errorOccurred, &loop, &QEventLoop::quit);
      
      1 Reply Last reply
      1
      • A acetone

        In Qt6, I've found that the bundle identified in the topic title sometimes has a dead lock. I have never noticed this before.

        QNetworkRequest request(url);
        auto reply = networkManager.post(request, multiPart);
        
        QEventLoop loop;
        QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
        loop.exec();
        

        Pure classic combination for some REST API requests.

        As it turned out, in some scenarios reply does not emit the QNetworkReply::finished signal and the thread hangs forever.

        I found a not-so-pretty but workable solution:

        #define REQUEST_DEADLOCK_SAVER \
        QTimer timer;\
            timer.setSingleShot(true);\
            timer.setInterval(REQUEST_TIMEOUT);\
            QObject::connect(&timer, &QTimer::timeout, [&loop](){\
                    qWarning() << "Network request dropped by timeout";\
                    loop.quit();\
            });\
            QObject::connect(reply, &QNetworkReply::finished, &timer, &QTimer::stop);\
            timer.start();
        

        Use it like this:

        QNetworkRequest request(url);
        auto reply = networkManager.post(request, multiPart) : this->aManager.get(request);
        
        QEventLoop loop;
        REQUEST_DEADLOCK_SAVER // <-------- solution
        QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
        loop.exec();
        

        Has anyone encountered a similar problem?

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

        @acetone said in QEventLoop + QNetworkRequest = dead lock:

        As it turned out, in some scenarios reply does not emit the QNetworkReply::finished signal

        Have you Googled for QNetworkReply::finished signal not emitted and read through the various hits?

        A 1 Reply Last reply
        0
        • JonBJ JonB

          @acetone said in QEventLoop + QNetworkRequest = dead lock:

          As it turned out, in some scenarios reply does not emit the QNetworkReply::finished signal

          Have you Googled for QNetworkReply::finished signal not emitted and read through the various hits?

          A Offline
          A Offline
          acetone
          wrote on last edited by
          #3

          @JonB Unfortunately, I can't find the answer in my case: I don't have infinity loops, all objects exist at the moment of request and its completion. The code used to work on Qt5 and now works on Qt6, but can go deadlocked after a few hours or days of uptime. It took me a long time to realize that this is where the hangup was happening)

          1 Reply Last reply
          0
          • A acetone

            In Qt6, I've found that the bundle identified in the topic title sometimes has a dead lock. I have never noticed this before.

            QNetworkRequest request(url);
            auto reply = networkManager.post(request, multiPart);
            
            QEventLoop loop;
            QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
            loop.exec();
            

            Pure classic combination for some REST API requests.

            As it turned out, in some scenarios reply does not emit the QNetworkReply::finished signal and the thread hangs forever.

            I found a not-so-pretty but workable solution:

            #define REQUEST_DEADLOCK_SAVER \
            QTimer timer;\
                timer.setSingleShot(true);\
                timer.setInterval(REQUEST_TIMEOUT);\
                QObject::connect(&timer, &QTimer::timeout, [&loop](){\
                        qWarning() << "Network request dropped by timeout";\
                        loop.quit();\
                });\
                QObject::connect(reply, &QNetworkReply::finished, &timer, &QTimer::stop);\
                timer.start();
            

            Use it like this:

            QNetworkRequest request(url);
            auto reply = networkManager.post(request, multiPart) : this->aManager.get(request);
            
            QEventLoop loop;
            REQUEST_DEADLOCK_SAVER // <-------- solution
            QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
            loop.exec();
            

            Has anyone encountered a similar problem?

            jeremy_kJ Offline
            jeremy_kJ Offline
            jeremy_k
            wrote on last edited by
            #4

            @acetone said in QEventLoop + QNetworkRequest = dead lock:

            QEventLoop loop;
            

            Why use a nested event loop?

            Asking a question about code? http://eel.is/iso-c++/testcase/

            A 1 Reply Last reply
            0
            • jeremy_kJ jeremy_k

              @acetone said in QEventLoop + QNetworkRequest = dead lock:

              QEventLoop loop;
              

              Why use a nested event loop?

              A Offline
              A Offline
              acetone
              wrote on last edited by
              #5

              @jeremy_k said in QEventLoop + QNetworkRequest = dead lock:

              Why use a nested event loop?

              To create a blocking operation in a context where further action only makes sense after receiving a response from the server.

              jeremy_kJ 1 Reply Last reply
              0
              • A acetone

                @jeremy_k said in QEventLoop + QNetworkRequest = dead lock:

                Why use a nested event loop?

                To create a blocking operation in a context where further action only makes sense after receiving a response from the server.

                jeremy_kJ Offline
                jeremy_kJ Offline
                jeremy_k
                wrote on last edited by
                #6

                @acetone said in QEventLoop + QNetworkRequest = dead lock:

                @jeremy_k said in QEventLoop + QNetworkRequest = dead lock:

                Why use a nested event loop?

                To create a blocking operation in a context where further action only makes sense after receiving a response from the server.

                Don't do that. Qt is heavily tested in the default configuration, where there is a single event loop and no significant blocking operations. Bugs do occur, but they're found and fixed relatively rapidly on the common path. Code that subverts that path has a tendency to find broken corner cases.

                If you need a "blocking" operation, create a signal that indicates that the operation has completed, and allow everything else that relies on the event loop to continue as normal.

                Asking a question about code? http://eel.is/iso-c++/testcase/

                1 Reply Last reply
                3
                • A Offline
                  A Offline
                  acetone
                  wrote on last edited by
                  #7

                  So I simply needed handle one more signal:

                  QObject::connect(reply, &QNetworkReply::errorOccurred, &loop, &QEventLoop::quit);
                  
                  1 Reply Last reply
                  1
                  • A acetone has marked this topic as solved on

                  • Login

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