Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
5.15.19, 6.8.1
-
None
-
dc60c305a (dev), 7a69a40b5 (6.8)
Description
QQmlDataBlob destruction
QQmlDataBlob is a refcounted data structured used from the engine thread as well as from the type loader thread. Whichever of those drops the last reference will delete it.
The data blobs are linked to each other with "waitingFor" and "waitingOnMe" links. The "waitingFor" links are refcounted and therefore safe enough for this discussion. The "waitingOnMe" links are not refcounted to avoid reference cycles.
The dtor of QQmlDataBlob removes the blob to be deleted from all "waitingOnMe" lists of other blobs. This is inherently unsafe. Those lists may be read from on the other thread at the same time.
QQmlImportDatabase
The import database is usually used from the type loader thread, despite living in the QQmlEngine. The QQmlEngine can manipulate the import and plugins paths. We should make sure this doesn't interfere with any concurrent type loading on the type loader thread, for example by having some kind of lock the import database triggered by the first type being loaded.
Furthermore, QQmlEngine has a public method importPlugin(). This method is quite wrong already without any of the threading problems. You should let the type loader load your plugins. In addition, though, it's also wrong because it loads the plugin on the engine thread while at the same time the type loader thread may be loading other plugins, accessing the internals of QQmlImportDatabase. Luckily this method is deprecated since 6.4.
URL interceptors
URL interceptors currently live in the QQmlEngine but are exclusively used on the type loader thread. They should live in the type loader thread. URL interceptors can, of course be added and removed from the engine thread. Therefore, here too, we need some mechanism to make sure this only happens before any types are loaded.
QQmlEngine in the type loader thread
We needlessly pass the QML engine around in a lot of methods that are only called from the type loader thread. Most of the time we simply need the QQmlTypeLoader instead. Passing the engine is dangerous.
Network access manager
The network access manager factory currently also lives in the engine but is exclusively used on the type loader thread. This is conceptually the same as the import database and the URL interceptors, but the network access manger factory has a mutex to protect it from concurrent access.
Attachments
Issue Links
- split from
-
QTBUG-128269 QQmlEngine destructor hangs on QQmlTypeLoader::invalidate
- Closed
Gerrit Reviews
For Gerrit Dashboard: QTBUG-131721 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
608754,5 | QtQml: Move URL interceptors into the type loader | dev | qt/qtdeclarative | Status: NEW | 0 | 0 |
609749,3 | QtQml: Move import database into type loader | dev | qt/qtdeclarative | Status: NEW | 0 | 0 |
609762,4 | QtQml: Reduce usage of QQmlEngine in type loader thread | dev | qt/qtdeclarative | Status: NEW | 0 | 0 |
609764,3 | QtQml: Phrase the thread assertions as inline methods | dev | qt/qtdeclarative | Status: NEW | 0 | 0 |
610067,2 | WIP: QtQml: Cache configuration parameters in type loader | dev | qt/qtdeclarative | Status: NEW | -2 | 0 |
610933,1 | QtQml: Generalize the global/illegal names | dev | qt/qtdeclarative | Status: NEW | +1 | +1 |