aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2019-06-25 08:07:37 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2019-06-25 13:50:45 +0200
commitb1f238568214e6587b829d6695677e55a99b1d40 (patch)
tree0e7b0c4f99dd8ad0be16db6a81cf8e2c2c64282f /examples
parent4d9ffeff745a4a8bd31df7af85058d38383c5286 (diff)
Discourage having AsyncImageResponse inherit from QRunnable
As the AsyncImageResponse is owned by the qml engine, it should ideally live in the same thread. Else, when we call destroyLater() on it in the qml engine, we can run into various race coditions. see also commit c8827b444c23656f67feee2e3ebd4f2868ab3db7 Change-Id: I6e21ca4527281445e5f6df082f60b60838bb2eac Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'examples')
-rw-r--r--examples/quick/imageresponseprovider/imageresponseprovider.cpp71
1 files changed, 45 insertions, 26 deletions
diff --git a/examples/quick/imageresponseprovider/imageresponseprovider.cpp b/examples/quick/imageresponseprovider/imageresponseprovider.cpp
index 4f7c12b1d8..32510dbec8 100644
--- a/examples/quick/imageresponseprovider/imageresponseprovider.cpp
+++ b/examples/quick/imageresponseprovider/imageresponseprovider.cpp
@@ -57,40 +57,60 @@
#include <QImage>
#include <QThreadPool>
-class AsyncImageResponse : public QQuickImageResponse, public QRunnable
+class AsyncImageResponseRunnable : public QObject, public QRunnable
+{
+ Q_OBJECT
+
+signals:
+ void done(QImage image);
+
+public:
+ AsyncImageResponseRunnable(const QString &id, const QSize &requestedSize)
+ : m_id(id), m_requestedSize(requestedSize) {}
+
+ void run() override
+ {
+ auto image = QImage(50, 50, QImage::Format_RGB32);
+ if (m_id == QLatin1String("slow")) {
+ qDebug() << "Slow, red, sleeping for 5 seconds";
+ QThread::sleep(5);
+ image.fill(Qt::red);
+ } else {
+ qDebug() << "Fast, blue, sleeping for 1 second";
+ QThread::sleep(1);
+ image.fill(Qt::blue);
+ }
+ if (m_requestedSize.isValid())
+ image = image.scaled(m_requestedSize);
+
+ emit done(image);
+ }
+
+private:
+ QString m_id;
+ QSize m_requestedSize;
+};
+
+class AsyncImageResponse : public QQuickImageResponse
{
public:
- AsyncImageResponse(const QString &id, const QSize &requestedSize)
- : m_id(id), m_requestedSize(requestedSize)
+ AsyncImageResponse(const QString &id, const QSize &requestedSize, QThreadPool *pool)
{
- setAutoDelete(false);
+ auto runnable = new AsyncImageResponseRunnable(id, requestedSize);
+ connect(runnable, &AsyncImageResponseRunnable::done, this, &AsyncImageResponse::handleDone);
+ pool->start(runnable);
}
- QQuickTextureFactory *textureFactory() const override
- {
- return QQuickTextureFactory::textureFactoryForImage(m_image);
+ void handleDone(QImage image) {
+ m_image = image;
+ emit finished();
}
- void run() override
+ QQuickTextureFactory *textureFactory() const override
{
- m_image = QImage(50, 50, QImage::Format_RGB32);
- if (m_id == "slow") {
- qDebug() << "Slow, red, sleeping for 5 seconds";
- QThread::sleep(5);
- m_image.fill(Qt::red);
- } else {
- qDebug() << "Fast, blue, sleeping for 1 second";
- QThread::sleep(1);
- m_image.fill(Qt::blue);
- }
- if (m_requestedSize.isValid())
- m_image = m_image.scaled(m_requestedSize);
-
- emit finished();
+ return QQuickTextureFactory::textureFactoryForImage(m_image);
}
- QString m_id;
- QSize m_requestedSize;
QImage m_image;
};
@@ -99,8 +119,7 @@ class AsyncImageProvider : public QQuickAsyncImageProvider
public:
QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override
{
- AsyncImageResponse *response = new AsyncImageResponse(id, requestedSize);
- pool.start(response);
+ AsyncImageResponse *response = new AsyncImageResponse(id, requestedSize, &pool);
return response;
}