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

QtFuture::whenAny continuation gets called if a QtFuture::connect object gets deleted

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P1: Critical
    • None
    • 6.5.2
    • Core: QtConcurrent
    • None
    • Linux/X11

    Description

      Hi,

      I have found out, that if you use QtFuture::whenAny with a QtFuture::connect QFuture, the continuation for the whenAny QFuture gets called, if you delete the original object (the one you called QtFuture::connect on). Here's an example:

      #include <QCoreApplication>
      #include <QFuture>
      #include <QTimer>
      int main(int argc, char* argv[])
      {
          QCoreApplication app(argc, argv);
          QTimer::singleShot(0, [] {
              auto timer = new QTimer();
              QtFuture::whenAny(
                  QtFuture::connect(timer, &QTimer::timeout).then([] {
                  return 1;
              })).then([] (const std::variant<QFuture<int>>& result) {
                  std::get<0>(result).result();
              });
              delete timer;
          });
          return QCoreApplication::exec();
      }
      

      The second .then callback gets called. Additionally, the `result` QFuture is invalid and calling .result() gives me a null-deref error, which is ok, according to the doc. However, in my opinion, there's no reason it should be called in the first place, because the timer wasn't even started. If I remove the whenAny call, everything works fine again. Additionally, if I add a context object `timer` to either of the .then() calls (or both), I'll get this assertion:

      ASSERT: "context" in file /usr/include/qt6/QtCore/qfuture_impl.h, line 598
      Aborted (core dumped)
      

      The context object issue is also present even when not using whenAny, so I'm not sure if they're related:

      #include <QCoreApplication>
      #include <QFuture>
      #include <QTimer>
      
      int main(int argc, char* argv[])
      {
          QCoreApplication app(argc, argv);
          QTimer::singleShot(0, [] {
              auto timer = new QTimer();
              QtFuture::connect(timer, &QTimer::timeout).then(timer, [] (auto) {});
              delete timer;
          });
          return QCoreApplication::exec();
      }
      

      I have looked at other issues, and it seems to me, that https://bugreports.qt.io/browse/QTBUG-107541 might be related, but I'm not sure.

      Attachments

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

        Activity

          People

            cnn Qt Core & Network
            syyyr Václav Kubernát
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes