Skip to content

Commit a87dbf0

Browse files
author
Samuel Rødal
committed
Fixed race condition in raster paint engine.
We need to protect the gradient cache accesses with a mutex. Task-number: QTBUG-14614 Reviewed-by: Bradley T. Hughes
1 parent e5ef6f5 commit a87dbf0

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

src/gui/painting/qpaintengine_raster.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4811,6 +4811,7 @@ class QGradientCache
48114811
for (int i = 0; i < stops.size() && i <= 2; i++)
48124812
hash_val += stops[i].second.rgba();
48134813

4814+
QMutexLocker lock(&mutex);
48144815
QGradientColorTableHash::const_iterator it = cache.constFind(hash_val);
48154816

48164817
if (it == cache.constEnd())
@@ -4844,6 +4845,7 @@ class QGradientCache
48444845
}
48454846

48464847
QGradientColorTableHash cache;
4848+
QMutex mutex;
48474849
};
48484850

48494851
void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, int opacity) const

tests/auto/qpainter/tst_qpainter.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ private slots:
251251

252252
void QTBUG5939_attachPainterPrivate();
253253

254+
void QTBUG14614_gradientCacheRaceCondition();
255+
254256
private:
255257
void fillData();
256258
void setPenColor(QPainter& p);
@@ -4458,6 +4460,36 @@ void tst_QPainter::QTBUG5939_attachPainterPrivate()
44584460
QCOMPARE(widget->deviceTransform, proxy->deviceTransform);
44594461
}
44604462

4463+
class GradientProducer : public QThread
4464+
{
4465+
protected:
4466+
void run();
4467+
};
4468+
4469+
void GradientProducer::run()
4470+
{
4471+
QImage image(1, 1, QImage::Format_RGB32);
4472+
QPainter p(&image);
4473+
4474+
for (int i = 0; i < 1000; ++i) {
4475+
QLinearGradient g;
4476+
g.setColorAt(0, QColor(i % 256, 0, 0));
4477+
g.setColorAt(1, Qt::white);
4478+
4479+
p.fillRect(image.rect(), g);
4480+
}
4481+
}
4482+
4483+
void tst_QPainter::QTBUG14614_gradientCacheRaceCondition()
4484+
{
4485+
const int threadCount = 16;
4486+
GradientProducer producers[threadCount];
4487+
for (int i = 0; i < threadCount; ++i)
4488+
producers[i].start();
4489+
for (int i = 0; i < threadCount; ++i)
4490+
producers[i].wait();
4491+
}
4492+
44614493
QTEST_MAIN(tst_QPainter)
44624494

44634495
#include "tst_qpainter.moc"

0 commit comments

Comments
 (0)