diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2017-01-10 12:49:11 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2017-01-14 18:18:01 +0000 |
commit | 7d898ae38e42f44dabcc972ad81cb7f05ecd8ad3 (patch) | |
tree | 73bf5be1439692f408281f6f6e3cf2be9082b229 /src/gui/painting/qdrawhelper_p.h | |
parent | 610c7da075789c1ae736c4a016ef822a4e500f29 (diff) |
QGradientCache: fix a new/delete mismatch
Commit f839f536 fixed a data race in the gradient cache by
reference-counting the CacheInfo objects stored in the cache. To this
end, QSpanData gained a ref-counted pointer to the CacheInfo whose
members it references to keep the object alive for as long as the
QSpanData object needs it. However, since CacheInfo is only later
defined in qpaintengine_raster.cpp, the counted pointer's payload was
chosen as CacheInfo's base class, QSharedData.
As it turns out, e.g. in the QPainter test, the data race was real and
so QSpanData ends up being the entity that destroys (at least some)
CacheInfos, either in its destructor, or in the setup() method. Since
QSharedData's destructor is not virtual, and
QExplicitlySharedDataPointer<QSharedData> knows nothing of the
CacheInfo-ness of its payload, we end up calling the destructor of the
base class, and not the CacheInfo one.
Fix by using QSharedPointer instead, which stores the correct deleter
internally. Ideally, QSpanData would contain a QSharedPointer<const
void>, but QSharedPointer's implementation is deficient in that
respect and does not compile when instantiated with void, and we can't
use std::shared_ptr, yet, so introduce an arbitrary base class,
Pinnable, to be used instead.
Change-Id: I5573c599d5464278d3a8e4248d887ef9ffcd7b70
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'src/gui/painting/qdrawhelper_p.h')
-rw-r--r-- | src/gui/painting/qdrawhelper_p.h | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index e537c343bb..0e46962784 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -64,6 +64,8 @@ #include "private/qrasterdefs_p.h" #include <private/qsimd_p.h> +#include <QtCore/qsharedpointer.h> + QT_BEGIN_NAMESPACE #if defined(Q_CC_GNU) @@ -335,7 +337,11 @@ struct QSpanData QGradientData gradient; QTextureData texture; }; - QExplicitlySharedDataPointer<const QSharedData> cachedGradient; + class Pinnable { + protected: + ~Pinnable() {} + }; // QSharedPointer<const void> is not supported + QSharedPointer<const Pinnable> cachedGradient; void init(QRasterBuffer *rb, const QRasterPaintEngine *pe); |