From e6c5e06c0879a80ecff01b316a4fc148b3646437 Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Tue, 28 Feb 2012 14:04:38 +1000 Subject: [PATCH] Fix crash in QDeclarativePixmapStore global static dtor Due to the undefined ordering of global static dtors, the QDPS dtor could run after the texture factories were deleted. Thus, the QDPS dtor cannot call the cost() method of the pixmap data during its destructor, as this could cause a crash. Change-Id: I5d23066dc57e1992cf9d1c13d514f06c431bc752 Reviewed-by: Alan Alpert --- src/declarative/qml/qdeclarativeimageprovider.h | 2 +- src/quick/util/qdeclarativepixmapcache.cpp | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/declarative/qml/qdeclarativeimageprovider.h b/src/declarative/qml/qdeclarativeimageprovider.h index 55a5ca2..16af452 100644 --- a/src/declarative/qml/qdeclarativeimageprovider.h +++ b/src/declarative/qml/qdeclarativeimageprovider.h @@ -58,7 +58,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeTextureFactory : public QObject { public: QDeclarativeTextureFactory(); - ~QDeclarativeTextureFactory(); + virtual ~QDeclarativeTextureFactory(); virtual QSGTexture *createTexture(QQuickCanvas *canvas) const = 0; virtual QSize textureSize() const = 0; diff --git a/src/quick/util/qdeclarativepixmapcache.cpp b/src/quick/util/qdeclarativepixmapcache.cpp index 95cbd36..1f187a7 100644 --- a/src/quick/util/qdeclarativepixmapcache.cpp +++ b/src/quick/util/qdeclarativepixmapcache.cpp @@ -762,6 +762,8 @@ void QDeclarativePixmapStore::unreferencePixmap(QDeclarativePixmapData *data) data->nextUnreferenced = m_unreferencedPixmaps; data->prevUnreferencedPtr = &m_unreferencedPixmaps; + if (!m_destroying) // the texture factories may have been cleaned up already. + m_unreferencedCost += data->cost(); m_unreferencedPixmaps = data; if (m_unreferencedPixmaps->nextUnreferenced) { @@ -772,8 +774,6 @@ void QDeclarativePixmapStore::unreferencePixmap(QDeclarativePixmapData *data) if (!m_lastUnreferencedPixmap) m_lastUnreferencedPixmap = data; - m_unreferencedCost += data->cost(); - shrinkCache(-1); // Shrink the cache incase it has become larger than cache_limit if (m_timerId == -1 && m_unreferencedPixmaps && !m_destroying) @@ -810,8 +810,10 @@ void QDeclarativePixmapStore::shrinkCache(int remove) data->prevUnreferencedPtr = 0; data->prevUnreferenced = 0; - remove -= data->cost(); - m_unreferencedCost -= data->cost(); + if (!m_destroying) { + remove -= data->cost(); + m_unreferencedCost -= data->cost(); + } data->removeFromCache(); delete data; } -- 2.7.4