Get rid of the evilness of Q_GLOBAL_STATIC_WITH_INITIALIZER
That macro is a nightmare. It leads to writing code that is thread-unsafe or other problems. So rewrite the code that used this macro to use special-purpose classes with constructors. This commit does not introduce new errors. The FIXME in qicon.cpp (qtIconCache()) was a condition already present. It does fix the race conditions that were present in qbrush.cpp nullBrushInstance() and qfontengine.cpp qt_grayPalette(). Specialising QGlobalStatic is also evil. Change-Id: I039311f6a5ac9ea4ad7b310b870a2adf888da7e5 Merge-request: 10 Reviewed-by: Olivier Goffart <olivier.goffart@nokia.com> Reviewed-on: http://codereview.qt.nokia.com/1895 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
This commit is contained in:
parent
de587d736a
commit
6d3c064302
@ -107,8 +107,18 @@ QT_BEGIN_NAMESPACE
|
|||||||
static QBasicAtomicInt serialNumCounter = Q_BASIC_ATOMIC_INITIALIZER(1);
|
static QBasicAtomicInt serialNumCounter = Q_BASIC_ATOMIC_INITIALIZER(1);
|
||||||
|
|
||||||
static void qt_cleanup_icon_cache();
|
static void qt_cleanup_icon_cache();
|
||||||
typedef QCache<QString, QIcon> IconCache;
|
namespace {
|
||||||
Q_GLOBAL_STATIC_WITH_INITIALIZER(IconCache, qtIconCache, qAddPostRoutine(qt_cleanup_icon_cache))
|
class IconCache: public QCache<QString, QIcon>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IconCache()
|
||||||
|
{
|
||||||
|
// ### FIXME: needs to be re-added if qApp is re-created
|
||||||
|
qAddPostRoutine(qt_cleanup_icon_cache);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Q_GLOBAL_STATIC(IconCache, qtIconCache)
|
||||||
|
|
||||||
static void qt_cleanup_icon_cache()
|
static void qt_cleanup_icon_cache()
|
||||||
{
|
{
|
||||||
|
@ -112,6 +112,7 @@ QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
|
|||||||
return pm;
|
return pm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qt_cleanup_brush_pattern_image_cache();
|
||||||
class QBrushPatternImageCache
|
class QBrushPatternImageCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -123,6 +124,7 @@ public:
|
|||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
|
qAddPostRoutine(qt_cleanup_brush_pattern_image_cache);
|
||||||
for (int style = Qt::Dense1Pattern; style <= Qt::DiagCrossPattern; ++style) {
|
for (int style = Qt::Dense1Pattern; style <= Qt::DiagCrossPattern; ++style) {
|
||||||
int i = style - Qt::Dense1Pattern;
|
int i = style - Qt::Dense1Pattern;
|
||||||
m_images[i][0] = QImage(qt_patternForBrush(style, 0), 8, 8, 1, QImage::Format_MonoLSB);
|
m_images[i][0] = QImage(qt_patternForBrush(style, 0), 8, 8, 1, QImage::Format_MonoLSB);
|
||||||
@ -153,11 +155,7 @@ private:
|
|||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void qt_cleanup_brush_pattern_image_cache();
|
Q_GLOBAL_STATIC(QBrushPatternImageCache, qt_brushPatternImageCache)
|
||||||
Q_GLOBAL_STATIC_WITH_INITIALIZER(QBrushPatternImageCache, qt_brushPatternImageCache,
|
|
||||||
{
|
|
||||||
qAddPostRoutine(qt_cleanup_brush_pattern_image_cache);
|
|
||||||
})
|
|
||||||
|
|
||||||
static void qt_cleanup_brush_pattern_image_cache()
|
static void qt_cleanup_brush_pattern_image_cache()
|
||||||
{
|
{
|
||||||
@ -339,33 +337,29 @@ struct QBrushDataPointerDeleter
|
|||||||
\sa Qt::BrushStyle, QPainter, QColor
|
\sa Qt::BrushStyle, QPainter, QColor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef QT_NO_THREAD
|
class QNullBrushData
|
||||||
// Special deleter that only deletes if the ref-count goes to zero
|
|
||||||
template <>
|
|
||||||
class QGlobalStaticDeleter<QBrushData>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QGlobalStatic<QBrushData> &globalStatic;
|
QBrushData *brush;
|
||||||
QGlobalStaticDeleter(QGlobalStatic<QBrushData> &_globalStatic)
|
QNullBrushData() : brush(new QBrushData)
|
||||||
: globalStatic(_globalStatic)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
inline ~QGlobalStaticDeleter()
|
|
||||||
{
|
{
|
||||||
if (!globalStatic.pointer->ref.deref())
|
brush->ref = 1;
|
||||||
delete globalStatic.pointer;
|
brush->style = Qt::BrushStyle(0);
|
||||||
globalStatic.pointer = 0;
|
brush->color = Qt::black;
|
||||||
globalStatic.destroyed = true;
|
}
|
||||||
|
~QNullBrushData()
|
||||||
|
{
|
||||||
|
if (!brush->ref.deref())
|
||||||
|
delete brush;
|
||||||
|
brush = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
Q_GLOBAL_STATIC_WITH_INITIALIZER(QBrushData, nullBrushInstance,
|
Q_GLOBAL_STATIC(QNullBrushData, nullBrushInstance_holder)
|
||||||
{
|
static QBrushData *nullBrushInstance()
|
||||||
x->ref = 1;
|
{
|
||||||
x->style = Qt::BrushStyle(0);
|
return nullBrushInstance_holder()->brush;
|
||||||
x->color = Qt::black;
|
}
|
||||||
})
|
|
||||||
|
|
||||||
static bool qbrush_check_type(Qt::BrushStyle style) {
|
static bool qbrush_check_type(Qt::BrushStyle style) {
|
||||||
switch (style) {
|
switch (style) {
|
||||||
|
@ -244,30 +244,25 @@ inline QPenPrivate::QPenPrivate(const QBrush &_brush, qreal _width, Qt::PenStyle
|
|||||||
static const Qt::PenCapStyle qpen_default_cap = Qt::SquareCap;
|
static const Qt::PenCapStyle qpen_default_cap = Qt::SquareCap;
|
||||||
static const Qt::PenJoinStyle qpen_default_join = Qt::BevelJoin;
|
static const Qt::PenJoinStyle qpen_default_join = Qt::BevelJoin;
|
||||||
|
|
||||||
#ifndef QT_NO_THREAD
|
class QPenDataHolder
|
||||||
// Special deleter that only deletes if the ref-count goes to zero
|
|
||||||
template <>
|
|
||||||
class QGlobalStaticDeleter<QPenPrivate>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QGlobalStatic<QPenPrivate> &globalStatic;
|
QPenData *pen;
|
||||||
QGlobalStaticDeleter(QGlobalStatic<QPenPrivate> &_globalStatic)
|
QPenDataHolder(const QBrush &brush, qreal width, Qt::PenStyle penStyle,
|
||||||
: globalStatic(_globalStatic)
|
Qt::PenCapStyle penCapStyle, Qt::PenJoinStyle _joinStyle)
|
||||||
|
: pen(new QPenData(brush, width, penStyle, penCapStyle, _joinStyle))
|
||||||
{ }
|
{ }
|
||||||
|
~QPenDataHolder()
|
||||||
inline ~QGlobalStaticDeleter()
|
|
||||||
{
|
{
|
||||||
if (!globalStatic.pointer->ref.deref())
|
if (!pen->ref.deref())
|
||||||
delete globalStatic.pointer;
|
delete pen;
|
||||||
globalStatic.pointer = 0;
|
pen = 0;
|
||||||
globalStatic.destroyed = true;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
Q_GLOBAL_STATIC_WITH_ARGS(QPenData, defaultPenInstance,
|
Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, defaultPenInstance,
|
||||||
(Qt::black, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join))
|
(Qt::black, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join))
|
||||||
Q_GLOBAL_STATIC_WITH_ARGS(QPenData, nullPenInstance,
|
Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, nullPenInstance,
|
||||||
(Qt::black, 0, Qt::NoPen, qpen_default_cap, qpen_default_join))
|
(Qt::black, 0, Qt::NoPen, qpen_default_cap, qpen_default_join))
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -276,7 +271,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QPenData, nullPenInstance,
|
|||||||
|
|
||||||
QPen::QPen()
|
QPen::QPen()
|
||||||
{
|
{
|
||||||
d = defaultPenInstance();
|
d = defaultPenInstance()->pen;
|
||||||
d->ref.ref();
|
d->ref.ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,7 +284,7 @@ QPen::QPen()
|
|||||||
QPen::QPen(Qt::PenStyle style)
|
QPen::QPen(Qt::PenStyle style)
|
||||||
{
|
{
|
||||||
if (style == Qt::NoPen) {
|
if (style == Qt::NoPen) {
|
||||||
d = nullPenInstance();
|
d = nullPenInstance()->pen;
|
||||||
d->ref.ref();
|
d->ref.ref();
|
||||||
} else {
|
} else {
|
||||||
d = new QPenData(Qt::black, 0, style, qpen_default_cap, qpen_default_join);
|
d = new QPenData(Qt::black, 0, style, qpen_default_cap, qpen_default_join);
|
||||||
|
@ -1110,12 +1110,19 @@ QByteArray QFontEngine::convertToPostscriptFontFamilyName(const QByteArray &fami
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_GLOBAL_STATIC_WITH_INITIALIZER(QVector<QRgb>, qt_grayPalette, {
|
class QRgbGreyPalette: public QVector<QRgb>
|
||||||
x->resize(256);
|
{
|
||||||
QRgb *it = x->data();
|
public:
|
||||||
for (int i = 0; i < x->size(); ++i, ++it)
|
QRgbGreyPalette()
|
||||||
*it = 0xff000000 | i | (i<<8) | (i<<16);
|
{
|
||||||
})
|
resize(256);
|
||||||
|
QRgb *it = data();
|
||||||
|
for (int i = 0; i < size(); ++i, ++it)
|
||||||
|
*it = 0xff000000 | i | (i<<8) | (i<<16);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC(QVector<QRgb>, qt_grayPalette)
|
||||||
|
|
||||||
const QVector<QRgb> &QFontEngine::grayPalette()
|
const QVector<QRgb> &QFontEngine::grayPalette()
|
||||||
{
|
{
|
||||||
|
@ -178,6 +178,8 @@ QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qt_cleanup_gl_share_widget();
|
||||||
|
|
||||||
//
|
//
|
||||||
// QGLWindowSurface
|
// QGLWindowSurface
|
||||||
//
|
//
|
||||||
@ -185,6 +187,8 @@ class QGLGlobalShareWidget
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QGLGlobalShareWidget() : firstPixmap(0), widgetRefCount(0), widget(0), initializing(false) {
|
QGLGlobalShareWidget() : firstPixmap(0), widgetRefCount(0), widget(0), initializing(false) {
|
||||||
|
// ### FIXME - readd the post routine if the qApp is recreated
|
||||||
|
qAddPostRoutine(qt_cleanup_gl_share_widget);
|
||||||
created = true;
|
created = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,11 +242,7 @@ private:
|
|||||||
bool QGLGlobalShareWidget::cleanedUp = false;
|
bool QGLGlobalShareWidget::cleanedUp = false;
|
||||||
bool QGLGlobalShareWidget::created = false;
|
bool QGLGlobalShareWidget::created = false;
|
||||||
|
|
||||||
static void qt_cleanup_gl_share_widget();
|
Q_GLOBAL_STATIC(QGLGlobalShareWidget, _qt_gl_share_widget)
|
||||||
Q_GLOBAL_STATIC_WITH_INITIALIZER(QGLGlobalShareWidget, _qt_gl_share_widget,
|
|
||||||
{
|
|
||||||
qAddPostRoutine(qt_cleanup_gl_share_widget);
|
|
||||||
})
|
|
||||||
|
|
||||||
static void qt_cleanup_gl_share_widget()
|
static void qt_cleanup_gl_share_widget()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user