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

Asynchronous Loader does not respect the incubation controller

    XMLWordPrintable

Details

    Description

      QQuickLoader has an auto test for asynchronous loading together with an incubation controller. Due to the asynchronous nature of tst_QQuickLoader::asynchronous(), the test is almost always passing, but randomly fails when the CPU load in CI is high enough. The failure is easy to reproduce by adding QTest::qWait() after loading the source, but before starting the incubation controller:

      diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
      index 50ded4d..e7ab2d5 100644
      --- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
      +++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
      @@ -920,50 +920,51 @@ void tst_QQuickLoader::asynchronous_data()
       void tst_QQuickLoader::asynchronous()
       {
           QFETCH(QUrl, qmlFile);
           QFETCH(QStringList, expectedWarnings);
       
           PeriodicIncubationController *controller = new PeriodicIncubationController;
           QQmlIncubationController *previous = engine.incubationController();
           engine.setIncubationController(controller);
           delete previous;
       
           QQmlComponent component(&engine, testFileUrl("asynchronous.qml"));
           QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
           QVERIFY(root);
       
           QQuickLoader *loader = root->findChild<QQuickLoader*>("loader");
           QVERIFY(loader);
       
           foreach (const QString &warning, expectedWarnings)
               QTest::ignoreMessage(QtWarningMsg, warning.toUtf8().constData());
       
           QVERIFY(!loader->item());
           QCOMPARE(loader->progress(), 0.0);
           root->setProperty("comp", qmlFile.toString());
           QMetaObject::invokeMethod(root, "loadComponent");
           QVERIFY(!loader->item());
      +    QTest::qWait(1000);
       
           if (expectedWarnings.isEmpty()) {
               QCOMPARE(loader->status(), QQuickLoader::Loading);
       
               controller->start();
               QVERIFY(!controller->incubated); // asynchronous compilation means not immediately compiled/incubating.
               QTRY_VERIFY(controller->incubated); // but should start incubating once compilation is complete.
               QTRY_VERIFY(loader->item());
               QCOMPARE(loader->progress(), 1.0);
               QCOMPARE(loader->status(), QQuickLoader::Ready);
           } else {
               QTRY_COMPARE(loader->progress(), 1.0);
               QTRY_COMPARE(loader->status(), QQuickLoader::Error);
           }
       
           delete root;
       }
      

      As soon as the asynchronous loading of the source is finished, QQuickLoader calls QQmlComponent::create(), which in turn calls QQmlEngitePrivate::incubate(). Thus, the incubation starts regardless of an incubation controller:

      #0  QQmlEnginePrivate::incubate (this=0x71c160, i=..., forContext=0x76d700) at qml/qqmlincubator.cpp:55
      #1  0x00007ffff74b96ab in QQmlComponent::create (this=0x755b20, incubator=..., context=0x7695a0, forContext=0x0) at qml/qqmlcomponent.cpp:1061
      #2  0x00007ffff7bfa963 in QQuickLoaderPrivate::_q_sourceLoaded (this=0x759750) at items/qquickloader.cpp:718
      #3  0x00007ffff7bfb1d5 in QQuickLoader::qt_static_metacall (_o=0x7596a0, _c=QMetaObject::InvokeMetaMethod, _id=8, _a=0x7fffffffc550) at .moc/debug-shared/moc_qquickloader_p.cpp:162
      #4  0x00007ffff61c7f96 in QMetaObject::activate (sender=0x755b20, signalOffset=3, local_signal_index=0, argv=0x7fffffffc550) at kernel/qobject.cpp:3479
      #5  0x00007ffff61c77ea in QMetaObject::activate (sender=0x755b20, m=0x7ffff7984020 <QQmlComponent::staticMetaObject>, local_signal_index=0, argv=0x7fffffffc550) at kernel/qobject.cpp:3354
      #6  0x00007ffff7665f48 in QQmlComponent::statusChanged (this=0x755b20, _t1=QQmlComponent::Ready) at .moc/debug-shared/moc_qqmlcomponent.cpp:247
      #7  0x00007ffff74b74fe in QQmlComponentPrivate::typeDataReady (this=0x769210) at qml/qqmlcomponent.cpp:332
      #8  0x00007ffff750ef26 in QQmlTypeData::completed (this=0x769710) at qml/qqmltypeloader.cpp:2022
      #9  0x00007ffff75095cf in QQmlDataLoaderThread::callCompletedMain (this=0x71ada0, b=0x769710) at qml/qqmltypeloader.cpp:805
      #10 0x00007ffff751d607 in QQmlThread::I::call (this=0x7fffe0036b70, thread=0x71ada0)
          at /home/jpnurmi/Projects/qt5-stable/qtbase/include/QtQml/5.1.0/QtQml/private/../../../../../../qtdeclarative/src/qml/qml/ftw/qqmlthread_p.h:295
      #11 0x00007ffff759f61a in QQmlThreadPrivate::mainEvent (this=0x71b8e0) at qml/ftw/qqmlthread.cpp:162
      #12 0x00007ffff759f3f0 in QQmlThreadPrivate::MainObject::event (this=0x71b938, e=0x7fffe00098b0) at qml/ftw/qqmlthread.cpp:122
      #13 0x00007ffff61879b6 in QCoreApplicationPrivate::notify_helper (this=0x644180, receiver=0x71b938, event=0x7fffe00098b0) at kernel/qcoreapplication.cpp:988
      #14 0x00007ffff618768c in QCoreApplication::notify (this=0x7fffffffdc80, receiver=0x71b938, event=0x7fffe00098b0) at kernel/qcoreapplication.cpp:933
      #15 0x00007ffff675efb2 in QGuiApplication::notify (this=0x7fffffffdc80, object=0x71b938, event=0x7fffe00098b0) at kernel/qguiapplication.cpp:1216
      #16 0x00007ffff6187594 in QCoreApplication::notifyInternal (this=0x7fffffffdc80, receiver=0x71b938, event=0x7fffe00098b0) at kernel/qcoreapplication.cpp:871
      #17 0x00007ffff618b215 in QCoreApplication::sendEvent (receiver=0x71b938, event=0x7fffe00098b0) at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:232
      #18 0x00007ffff61888de in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x6442b0) at kernel/qcoreapplication.cpp:1473
      #19 0x00007ffff618827f in QCoreApplication::sendPostedEvents (receiver=0x0, event_type=0) at kernel/qcoreapplication.cpp:1333
      #20 0x00007ffff61f8db3 in postEventSourceDispatch (s=0x650300) at kernel/qeventdispatcher_glib.cpp:279
      #21 0x00000036fc247a55 in g_main_dispatch (context=0x64ff20) at gmain.c:2715
      #22 g_main_context_dispatch (context=context@entry=0x64ff20) at gmain.c:3219
      #23 0x00000036fc247d88 in g_main_context_iterate (context=context@entry=0x64ff20, block=block@entry=0, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3290
      #24 0x00000036fc247e44 in g_main_context_iteration (context=0x64ff20, may_block=0) at gmain.c:3351
      #25 0x00007ffff61f9589 in QEventDispatcherGlib::processEvents (this=0x647cf0, flags=...) at kernel/qeventdispatcher_glib.cpp:426
      #26 0x00007fffeee995e6 in QPAEventDispatcherGlib::processEvents (this=0x647cf0, flags=...) at eventdispatchers/qeventdispatcher_glib.cpp:123
      #27 0x00007ffff6187ab9 in QCoreApplication::processEvents (flags=..., maxtime=1000) at kernel/qcoreapplication.cpp:1069
      #28 0x0000000000407cfa in QTest::qWait (ms=1000) at /home/jpnurmi/Projects/qt5-stable/qtbase/include/QtTest/../../src/testlib/qtestsystem.h:66
      

      Attachments

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

        Activity

          People

            laknoll Lars Knoll
            jpnurmi J-P Nurmi
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes