[vlc-commits] [Git][videolan/vlc][master] qt: do not use `QPluginLoader` in other threads

Steve Lhomme (@robUx4) gitlab at videolan.org
Fri Oct 3 09:26:03 UTC 2025



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
ed082fe3 by Fatih Uzunoglu at 2025-10-03T09:01:25+00:00
qt: do not use `QPluginLoader` in other threads

We can use blocking queued connection, because the plugins are
instantiated once and waiting can be tolerated.

This fixes the following warning getting spammed with Qt 6.9.2:

```
QObject::moveToThread: Current thread (0x7f6c48000f00) is not
the object's thread (0x7f6c140021d0).
Cannot move to target thread (0x7f6c48000f00)
```

- - - - -


2 changed files:

- modules/gui/qt/util/colorizedsvgicon.cpp
- modules/gui/qt/util/imagehelper.cpp


Changes:

=====================================
modules/gui/qt/util/colorizedsvgicon.cpp
=====================================
@@ -24,6 +24,8 @@
 #include <QPointer>
 #include <QWidget>
 #include <QFileInfo>
+#include <QThread>
+#include <QApplication>
 
 #include "util/color_svg_image_provider.hpp"
 
@@ -99,22 +101,32 @@ ColorizedSvgIcon ColorizedSvgIcon::colorizedIconForWidget(const QString &fileNam
 
 QIconEngine *ColorizedSvgIcon::svgIconEngine()
 {
-    static const auto plugin = []() -> QPointer<QIconEnginePlugin> {
+    static const auto plugin = []() {
+        QPointer<QIconEnginePlugin> plugin;
+
+        const auto retrieve = [&plugin]() {
 #ifdef QT_STATIC
-        const auto& staticPlugins = QPluginLoader::staticInstances();
-        const auto it = std::find_if(staticPlugins.begin(), staticPlugins.end(), [](QObject *obj) -> bool {
-            return obj->inherits("QSvgIconPlugin");
-        });
+            const auto& staticPlugins = QPluginLoader::staticInstances();
+            const auto it = std::find_if(staticPlugins.begin(), staticPlugins.end(), [](QObject *obj) -> bool {
+                return obj->inherits("QSvgIconPlugin");
+            });
 
-        if (it != staticPlugins.end())
-            return qobject_cast<QIconEnginePlugin*>(*it);
-        else
-            return nullptr;
+            if (it != staticPlugins.end())
+                plugin = qobject_cast<QIconEnginePlugin*>(*it);
 #else
-        QPluginLoader loader(QStringLiteral("iconengines/qsvgicon")); // Official Qt plugin
-        // No need to check the metadata (or inherits `QSvgIconPlugin`), a plugin named "qsvgicon" should already support svg.
-        return qobject_cast<QIconEnginePlugin*>(loader.instance());
+            QPluginLoader loader(QStringLiteral("iconengines/qsvgicon")); // Official Qt plugin
+            // No need to check the metadata (or inherits `QSvgIconPlugin`), a plugin named "qsvgicon" should already support svg.
+            plugin = qobject_cast<QIconEnginePlugin*>(loader.instance());
 #endif
+        };
+
+        assert(qApp); // do not call before QApplication is constructed.
+        if (QThread::currentThread() == qApp->thread())
+            retrieve();
+        else
+            QMetaObject::invokeMethod(qApp, retrieve, Qt::BlockingQueuedConnection);
+
+        return plugin;
     }();
 
     if (!plugin)


=====================================
modules/gui/qt/util/imagehelper.cpp
=====================================
@@ -31,6 +31,7 @@
 #include <QImageIOHandler>
 #include <QPluginLoader>
 #include <QFile>
+#include <QThread>
 #include "imagehelper.hpp"
 
 
@@ -75,22 +76,32 @@ QPixmap ImageHelper::loadSvgToPixmap( const QString &path, qint32 i_width, qint3
 
 QImageIOHandler *ImageHelper::createSvgImageIOHandler()
 {
-    static const auto plugin = []() -> QPointer<QImageIOPlugin> {
+    static const auto plugin = []() {
+        QPointer<QImageIOPlugin> plugin;
+
+        const auto retrieve = [&plugin]() {
 #ifdef QT_STATIC
-        const auto& staticPlugins = QPluginLoader::staticInstances();
-        const auto it = std::find_if(staticPlugins.begin(), staticPlugins.end(), [](QObject *obj) -> bool {
-            return obj->inherits("QSvgPlugin");
-        });
+            const auto& staticPlugins = QPluginLoader::staticInstances();
+            const auto it = std::find_if(staticPlugins.begin(), staticPlugins.end(), [](QObject *obj) -> bool {
+                return obj->inherits("QSvgPlugin");
+            });
 
-        if (it != staticPlugins.end())
-            return qobject_cast<QImageIOPlugin*>(*it);
-        else
-            return nullptr;
+            if (it != staticPlugins.end())
+                plugin = qobject_cast<QImageIOPlugin*>(*it);
 #else
-        QPluginLoader loader(QStringLiteral("imageformats/qsvg")); // Official Qt plugin
-        // No need to check the metadata (or inherits `QSvgPlugin`), a plugin named "qsvg" should already support svg.
-        return qobject_cast<QImageIOPlugin*>(loader.instance());
+            QPluginLoader loader(QStringLiteral("imageformats/qsvg")); // Official Qt plugin
+            // No need to check the metadata (or inherits `QSvgPlugin`), a plugin named "qsvg" should already support svg.
+            plugin = qobject_cast<QImageIOPlugin*>(loader.instance());
 #endif
+        };
+
+        assert(qApp); // do not call before QApplication is constructed.
+        if (QThread::currentThread() == qApp->thread())
+            retrieve();
+        else
+            QMetaObject::invokeMethod(qApp, retrieve, Qt::BlockingQueuedConnection);
+
+        return plugin;
     }();
 
     if (!plugin)



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/ed082fe33d27a3f4a4b52b35252b9880e734013d

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/ed082fe33d27a3f4a4b52b35252b9880e734013d
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list