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

Asynchronous Loader does not respect the incubation controller

XMLWordPrintable

      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
      

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

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

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes