summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorOlivier Goffart <olivier.goffart@nokia.com>2010-08-17 13:38:33 (GMT)
committerOlivier Goffart <olivier.goffart@nokia.com>2010-08-19 08:47:11 (GMT)
commitf894befedf669fb864a500b0aa395157ff0fb929 (patch)
treec5bc53dcd98dbce2471e23e7014c2a30247e8941 /tests
parentf6cfafde26b4735965be8df0d11e9d7c297c75b9 (diff)
downloadQt-f894befedf669fb864a500b0aa395157ff0fb929.zip
Qt-f894befedf669fb864a500b0aa395157ff0fb929.tar.gz
Qt-f894befedf669fb864a500b0aa395157ff0fb929.tar.bz2
QDeclarativeImageProvider: Do not keep the global declarative mutex locked when processing.
The point is to be able to process images in a thread. If the mutex is locked, this is useless. Use case is a slow QDeclarativeImageProvider that generates thumbmails from large files. Even with the asynchronous attribute set to true, the gui thread would be blocked by the mutex. By using QSharedPointer, I also fix the leak of the providers (which were not deleted) Reviewed-by: Martin Jones
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp105
1 files changed, 97 insertions, 8 deletions
diff --git a/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp b/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp
index e0b46f0..4a9224e 100644
--- a/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp
+++ b/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp
@@ -44,6 +44,7 @@
#include <QtDeclarative/qdeclarativeimageprovider.h>
#include <private/qdeclarativeimage_p.h>
#include <QImageReader>
+#include <QWaitCondition>
#ifdef Q_OS_SYMBIAN
// In Symbian OS test data is located in applications private dir
@@ -85,6 +86,8 @@ private slots:
void removeProvider_data();
void removeProvider();
+ void threadTest();
+
private:
QString newImageFileName() const;
void fillRequestTestsData(const QString &id);
@@ -95,9 +98,15 @@ private:
class TestQImageProvider : public QDeclarativeImageProvider
{
public:
- TestQImageProvider()
- : QDeclarativeImageProvider(Image)
+ TestQImageProvider(bool *deleteWatch = 0)
+ : QDeclarativeImageProvider(Image), deleteWatch(deleteWatch)
+ {
+ }
+
+ ~TestQImageProvider()
{
+ if (deleteWatch)
+ *deleteWatch = true;
}
QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize)
@@ -114,6 +123,8 @@ public:
image = image.scaled(requestedSize);
return image;
}
+
+ bool *deleteWatch;
};
Q_DECLARE_METATYPE(TestQImageProvider*);
@@ -121,11 +132,17 @@ Q_DECLARE_METATYPE(TestQImageProvider*);
class TestQPixmapProvider : public QDeclarativeImageProvider
{
public:
- TestQPixmapProvider()
- : QDeclarativeImageProvider(Pixmap)
+ TestQPixmapProvider(bool *deleteWatch = 0)
+ : QDeclarativeImageProvider(Pixmap), deleteWatch(deleteWatch)
{
}
+ ~TestQPixmapProvider()
+ {
+ if (deleteWatch)
+ *deleteWatch = true;
+ }
+
QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize)
{
if (id == QLatin1String("no-such-file.png"))
@@ -140,6 +157,8 @@ public:
image = image.scaled(requestedSize);
return image;
}
+
+ bool *deleteWatch;
};
Q_DECLARE_METATYPE(TestQPixmapProvider*);
@@ -225,7 +244,9 @@ void tst_qdeclarativeimageprovider::requestImage_sync_data()
void tst_qdeclarativeimageprovider::requestImage_sync()
{
- runTest(false, new TestQImageProvider);
+ bool deleteWatch = false;
+ runTest(false, new TestQImageProvider(&deleteWatch));
+ QVERIFY(deleteWatch);
}
void tst_qdeclarativeimageprovider::requestImage_async_data()
@@ -235,7 +256,9 @@ void tst_qdeclarativeimageprovider::requestImage_async_data()
void tst_qdeclarativeimageprovider::requestImage_async()
{
- runTest(true, new TestQImageProvider);
+ bool deleteWatch = false;
+ runTest(true, new TestQImageProvider(&deleteWatch));
+ QVERIFY(deleteWatch);
}
void tst_qdeclarativeimageprovider::requestPixmap_sync_data()
@@ -245,13 +268,15 @@ void tst_qdeclarativeimageprovider::requestPixmap_sync_data()
void tst_qdeclarativeimageprovider::requestPixmap_sync()
{
- runTest(false, new TestQPixmapProvider);
+ bool deleteWatch = false;
+ runTest(false, new TestQPixmapProvider(&deleteWatch));
+ QVERIFY(deleteWatch);
}
void tst_qdeclarativeimageprovider::requestPixmap_async()
{
QDeclarativeEngine engine;
- QDeclarativeImageProvider *provider = new TestQPixmapProvider;
+ QDeclarativeImageProvider *provider = new TestQPixmapProvider();
engine.addImageProvider("test", provider);
QVERIFY(engine.imageProvider("test") != 0);
@@ -305,6 +330,70 @@ void tst_qdeclarativeimageprovider::removeProvider()
delete obj;
}
+class TestThreadProvider : public QDeclarativeImageProvider
+{
+ public:
+ TestThreadProvider() : QDeclarativeImageProvider(Image), ok(false) {}
+
+ ~TestThreadProvider() {}
+
+ QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize)
+ {
+ mutex.lock();
+ if (!ok)
+ cond.wait(&mutex);
+ mutex.unlock();
+ QVector<int> v;
+ for (int i = 0; i < 10000; i++)
+ v.prepend(i); //do some computation
+ QImage image(50,50, QImage::Format_RGB32);
+ image.fill(QColor(id).rgb());
+ if (size)
+ *size = image.size();
+ if (requestedSize.isValid())
+ image = image.scaled(requestedSize);
+ return image;
+ }
+
+ QWaitCondition cond;
+ QMutex mutex;
+ bool ok;
+};
+
+
+void tst_qdeclarativeimageprovider::threadTest()
+{
+ QDeclarativeEngine engine;
+
+ TestThreadProvider *provider = new TestThreadProvider;
+
+ engine.addImageProvider("test_thread", provider);
+ QVERIFY(engine.imageProvider("test_thread") != 0);
+
+ QString componentStr = "import Qt 4.7\nItem { \n"
+ "Image { source: \"image://test_thread/blue\"; asynchronous: true; }\n"
+ "Image { source: \"image://test_thread/red\"; asynchronous: true; }\n"
+ "Image { source: \"image://test_thread/green\"; asynchronous: true; }\n"
+ "Image { source: \"image://test_thread/yellow\"; asynchronous: true; }\n"
+ " }";
+ QDeclarativeComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QObject *obj = component.create();
+ //MUST not deadlock
+ QVERIFY(obj != 0);
+ QList<QDeclarativeImage *> images = obj->findChildren<QDeclarativeImage *>();
+ QCOMPARE(images.count(), 4);
+ QTest::qWait(100);
+ foreach(QDeclarativeImage *img, images) {
+ QCOMPARE(img->status(), QDeclarativeImage::Loading);
+ }
+ provider->ok = true;
+ provider->cond.wakeAll();
+ foreach(QDeclarativeImage *img, images) {
+ TRY_WAIT(img->status() == QDeclarativeImage::Ready);
+ }
+}
+
QTEST_MAIN(tst_qdeclarativeimageprovider)