Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-120201

QFuture::onFailed() fails when expecting QFuture::resultCount() > 1

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.2.10, 6.5.3, 6.6.1
    • None
    • Windows 10 22H2

    Description

      Problem 1: All results are discarded except for the first

      Code

      #include <QtConcurrentMap>
      
      int main()
      {
          QList<int> numbers{1, 2, 3};
          QFuture<int> f1 = QtConcurrent::mapped(numbers, [](int i) -> int {
              return i*i;
          });
          QFuture<int> f2 = f1.onFailed([]() -> int {
              return -1;
          });
      
          qDebug() << "Without failure handler:" << f1.results();
          qDebug() << "With failure handler:" << f2.results();
      }
      

       

      Expected outcome
      https://doc.qt.io/qt-6/qfuture.html#onFailed says "The returned future behaves exactly as this future (has the same state and result) unless this future fails with an exception" so I'd expect the following:

      Without failure handler: QList(1, 4, 9)
      With failure handler: QList(1, 4, 9)
      

       

      Actual outcome

      Without failure handler: QList(1, 4, 9)
      With failure handler: QList(1)
      

       

       

      Problem 2: Assertion if there is a valid result along with an exception (MSVC + Qt >= 6.5 only?)

      Code

      #include <QtConcurrentMap>
      
      int main()
      {
          QList<int> numbers{1, 2};
          QFuture<int> f = QtConcurrent::mapped(numbers, [](int i) -> int {
              if (i % 2 != 0) { // Negating this condition still produces the assertion without changing the order of processing
                  qDebug() << "Processing" << i << "OK";
              } else {
                  qDebug() << "Processing" << i << "FAILED";
                  throw std::runtime_error("FAILED");
              }
              return i*i;
          }).onFailed([]() -> int {
              return -1;
          });
      
          qDebug() << "Results:" << f.results();
      }
      
      

       

      Expected outcome
      I'd expect i*i where the map function didn't throw an exception, and -1 where the map function threw an exception:

      Processing 1 OK
      Processing 2 FAILED
      Results: QList(1, -1)
      

       

      Actual outcome
      I was only able to reproduce this using MSVC 2019/2022 with + Qt 6.5.3/Qt6.6.1/6.7.0-snapshot:

      Processing 1 OK
      Processing 2 FAILED
      ASSERT: "m_results.isEmpty()" in file C:\Users\qt\work\qt\qtbase\src\corelib\thread\qresultstore.cpp, line 122
      

       

      MSVC + Qt 6.2.10 or MinGW with any Qt version produces a single result like Problem 1 (except that it keeps the failed result, not the first result):

      Processing 1 OK
      Processing 2 FAILED
      Results: QList(-1)
      

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            thiago Thiago Macieira
            skoh-qt Sze Howe Koh
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes