mirror of
https://bitbucket.org/smil3y/katie.git
synced 2025-02-24 02:42:55 +00:00
get rid of the subject to race condition Q_GLOBAL_STATIC_WITH_INITIALIZER() macro [ci reset]
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
6efbe30ee4
commit
69e4c8a3ac
14 changed files with 36 additions and 171 deletions
|
@ -665,8 +665,6 @@ katie_generate_obsolete(QFutureIterator QtCore qfuture.h)
|
||||||
katie_generate_obsolete(QFutureWatcherBase QtCore qfuturewatcher.h)
|
katie_generate_obsolete(QFutureWatcherBase QtCore qfuturewatcher.h)
|
||||||
katie_generate_obsolete(QGenericArgument QtCore qobjectdefs.h)
|
katie_generate_obsolete(QGenericArgument QtCore qobjectdefs.h)
|
||||||
katie_generate_obsolete(QGenericReturnArgument QtCore qobjectdefs.h)
|
katie_generate_obsolete(QGenericReturnArgument QtCore qobjectdefs.h)
|
||||||
katie_generate_obsolete(QGlobalStaticDeleter QtCore qglobal.h)
|
|
||||||
katie_generate_obsolete(QGlobalStatic QtCore qglobal.h)
|
|
||||||
katie_generate_obsolete(QGradient QtGui qbrush.h)
|
katie_generate_obsolete(QGradient QtGui qbrush.h)
|
||||||
katie_generate_obsolete(QGradientStop QtGui qbrush.h)
|
katie_generate_obsolete(QGradientStop QtGui qbrush.h)
|
||||||
katie_generate_obsolete(QGradientStops QtGui qbrush.h)
|
katie_generate_obsolete(QGradientStops QtGui qbrush.h)
|
||||||
|
|
|
@ -62,8 +62,6 @@ include/katie/QtCore/QFutureWatcher
|
||||||
include/katie/QtCore/QFutureWatcherBase
|
include/katie/QtCore/QFutureWatcherBase
|
||||||
include/katie/QtCore/QGenericArgument
|
include/katie/QtCore/QGenericArgument
|
||||||
include/katie/QtCore/QGenericReturnArgument
|
include/katie/QtCore/QGenericReturnArgument
|
||||||
include/katie/QtCore/QGlobalStatic
|
|
||||||
include/katie/QtCore/QGlobalStaticDeleter
|
|
||||||
include/katie/QtCore/QHash
|
include/katie/QtCore/QHash
|
||||||
include/katie/QtCore/QHashData
|
include/katie/QtCore/QHashData
|
||||||
include/katie/QtCore/QHashIterator
|
include/katie/QtCore/QHashIterator
|
||||||
|
|
|
@ -65,8 +65,6 @@ include/katie/QtCore/QFutureWatcher
|
||||||
include/katie/QtCore/QFutureWatcherBase
|
include/katie/QtCore/QFutureWatcherBase
|
||||||
include/katie/QtCore/QGenericArgument
|
include/katie/QtCore/QGenericArgument
|
||||||
include/katie/QtCore/QGenericReturnArgument
|
include/katie/QtCore/QGenericReturnArgument
|
||||||
include/katie/QtCore/QGlobalStatic
|
|
||||||
include/katie/QtCore/QGlobalStaticDeleter
|
|
||||||
include/katie/QtCore/QHash
|
include/katie/QtCore/QHash
|
||||||
include/katie/QtCore/QHashData
|
include/katie/QtCore/QHashData
|
||||||
include/katie/QtCore/QHashIterator
|
include/katie/QtCore/QHashIterator
|
||||||
|
|
|
@ -65,8 +65,6 @@ include/katie/QtCore/QFutureWatcher
|
||||||
include/katie/QtCore/QFutureWatcherBase
|
include/katie/QtCore/QFutureWatcherBase
|
||||||
include/katie/QtCore/QGenericArgument
|
include/katie/QtCore/QGenericArgument
|
||||||
include/katie/QtCore/QGenericReturnArgument
|
include/katie/QtCore/QGenericReturnArgument
|
||||||
include/katie/QtCore/QGlobalStatic
|
|
||||||
include/katie/QtCore/QGlobalStaticDeleter
|
|
||||||
include/katie/QtCore/QHash
|
include/katie/QtCore/QHash
|
||||||
include/katie/QtCore/QHashData
|
include/katie/QtCore/QHashData
|
||||||
include/katie/QtCore/QHashIterator
|
include/katie/QtCore/QHashIterator
|
||||||
|
|
|
@ -29,8 +29,6 @@ incmap = {
|
||||||
'QFutureWatcherBase': 'qfuturewatcher.h',
|
'QFutureWatcherBase': 'qfuturewatcher.h',
|
||||||
'QGenericArgument': 'qobjectdefs.h',
|
'QGenericArgument': 'qobjectdefs.h',
|
||||||
'QGenericReturnArgument': 'qobjectdefs.h',
|
'QGenericReturnArgument': 'qobjectdefs.h',
|
||||||
'QGlobalStatic': 'qglobal.h',
|
|
||||||
'QGlobalStaticDeleter': 'qglobal.h',
|
|
||||||
'QHashData': 'qhash.h',
|
'QHashData': 'qhash.h',
|
||||||
'QHashIterator': 'qhash.h',
|
'QHashIterator': 'qhash.h',
|
||||||
'QHashNode': 'qhash.h',
|
'QHashNode': 'qhash.h',
|
||||||
|
|
|
@ -261,8 +261,6 @@ classlist = [
|
||||||
"QGenericArgument",
|
"QGenericArgument",
|
||||||
"QGenericMatrix",
|
"QGenericMatrix",
|
||||||
"QGenericReturnArgument",
|
"QGenericReturnArgument",
|
||||||
"QGlobalStatic",
|
|
||||||
"QGlobalStaticDeleter",
|
|
||||||
"QGradient",
|
"QGradient",
|
||||||
"QGradientStop",
|
"QGradientStop",
|
||||||
"QGradientStops",
|
"QGradientStops",
|
||||||
|
|
|
@ -1727,25 +1727,6 @@ bool QInternal::activateCallbacks(void **parameters)
|
||||||
to it.
|
to it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
|
||||||
\macro Q_GLOBAL_STATIC_WITH_INITIALIZER(type, name, initializer)
|
|
||||||
\internal
|
|
||||||
|
|
||||||
Declares a global static variable with the specified \a type and \a name.
|
|
||||||
|
|
||||||
Use this macro to instantiate an object using the \a initializer specified
|
|
||||||
in a thread-safe way, creating a global pointer that can be used to refer
|
|
||||||
to it.
|
|
||||||
|
|
||||||
\warning This macro is subject to a race condition that can cause the object
|
|
||||||
to be constructed twice. However, if this occurs, the second instance will
|
|
||||||
be immediately deleted.
|
|
||||||
|
|
||||||
See also
|
|
||||||
\l{http://www.aristeia.com/publications.html}{"C++ and the perils of Double-Checked Locking"}
|
|
||||||
by Scott Meyers and Andrei Alexandrescu.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\macro QT_NAMESPACE
|
\macro QT_NAMESPACE
|
||||||
\internal
|
\internal
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#include <utility> // std::swap
|
#include <utility> // std::swap
|
||||||
#include <cstdint> // std::uintptr_t
|
#include <cstdint> // std::uintptr_t
|
||||||
|
#include <memory> // std::unique_ptr
|
||||||
|
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
typedef unsigned short ushort;
|
typedef unsigned short ushort;
|
||||||
|
@ -393,115 +394,20 @@ Q_CORE_EXPORT void qt_message_output(QtMsgType, const char *buf);
|
||||||
typedef void (*QtMsgHandler)(QtMsgType, const char *);
|
typedef void (*QtMsgHandler)(QtMsgType, const char *);
|
||||||
Q_CORE_EXPORT QtMsgHandler qInstallMsgHandler(QtMsgHandler);
|
Q_CORE_EXPORT QtMsgHandler qInstallMsgHandler(QtMsgHandler);
|
||||||
|
|
||||||
|
#define Q_GLOBAL_STATIC(TYPE, NAME) \
|
||||||
#if defined(QT_NO_THREAD)
|
static TYPE *NAME() \
|
||||||
|
{ \
|
||||||
template <typename T>
|
static std::unique_ptr<TYPE> this__StaticVar_(new TYPE); \
|
||||||
class QGlobalStatic
|
return this__StaticVar_.get(); \
|
||||||
{
|
|
||||||
public:
|
|
||||||
T *pointer;
|
|
||||||
inline QGlobalStatic(T *p) : pointer(p) { }
|
|
||||||
inline ~QGlobalStatic() { pointer = nullptr; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#define Q_GLOBAL_STATIC(TYPE, NAME) \
|
|
||||||
static TYPE *NAME() \
|
|
||||||
{ \
|
|
||||||
static TYPE thisVariable; \
|
|
||||||
static QGlobalStatic<TYPE > thisGlobalStatic(&thisVariable); \
|
|
||||||
return thisGlobalStatic.pointer; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \
|
#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \
|
||||||
static TYPE *NAME() \
|
static TYPE *NAME() \
|
||||||
{ \
|
{ \
|
||||||
static TYPE thisVariable ARGS; \
|
static std::unique_ptr<TYPE> this__StaticVar_(new TYPE ARGS); \
|
||||||
static QGlobalStatic<TYPE > thisGlobalStatic(&thisVariable); \
|
return this__StaticVar_.get(); \
|
||||||
return thisGlobalStatic.pointer; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER) \
|
|
||||||
static TYPE *NAME() \
|
|
||||||
{ \
|
|
||||||
static TYPE thisVariable; \
|
|
||||||
static QGlobalStatic<TYPE > thisGlobalStatic(nullptr); \
|
|
||||||
if (!thisGlobalStatic.pointer) { \
|
|
||||||
TYPE *x = thisGlobalStatic.pointer = &thisVariable; \
|
|
||||||
INITIALIZER; \
|
|
||||||
} \
|
|
||||||
return thisGlobalStatic.pointer; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // QT_NO_THREAD
|
|
||||||
|
|
||||||
// Forward declaration, since qatomic.h needs qglobal.h
|
|
||||||
template <typename T> class QAtomicPointer;
|
|
||||||
|
|
||||||
// POD for Q_GLOBAL_STATIC
|
|
||||||
template <typename T>
|
|
||||||
class QGlobalStatic
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QAtomicPointer<T> pointer;
|
|
||||||
bool destroyed;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Created as a function-local static to delete a QGlobalStatic<T>
|
|
||||||
template <typename T>
|
|
||||||
class QGlobalStaticDeleter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QGlobalStatic<T> &globalStatic;
|
|
||||||
QGlobalStaticDeleter(QGlobalStatic<T> &_globalStatic)
|
|
||||||
: globalStatic(_globalStatic)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
inline ~QGlobalStaticDeleter()
|
|
||||||
{
|
|
||||||
delete globalStatic.pointer;
|
|
||||||
globalStatic.pointer = nullptr;
|
|
||||||
globalStatic.destroyed = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#define Q_GLOBAL_STATIC(TYPE, NAME) \
|
|
||||||
static TYPE *NAME() \
|
|
||||||
{ \
|
|
||||||
static QGlobalStatic<TYPE > this__StaticVar_ \
|
|
||||||
= { QAtomicPointer<TYPE>(new TYPE), false }; \
|
|
||||||
static QGlobalStaticDeleter<TYPE > cleanup(this__StaticVar_); \
|
|
||||||
return this__StaticVar_.pointer; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \
|
|
||||||
static TYPE *NAME() \
|
|
||||||
{ \
|
|
||||||
static QGlobalStatic<TYPE > this__StaticVar_ \
|
|
||||||
= { QAtomicPointer<TYPE>(new TYPE ARGS), false }; \
|
|
||||||
static QGlobalStaticDeleter<TYPE > cleanup(this__StaticVar_); \
|
|
||||||
return this__StaticVar_.pointer; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER) \
|
|
||||||
static TYPE *NAME() \
|
|
||||||
{ \
|
|
||||||
static QGlobalStatic<TYPE > this__StaticVar_ \
|
|
||||||
= { QAtomicPointer<TYPE>(nullptr), false }; \
|
|
||||||
if (!this__StaticVar_.pointer && !this__StaticVar_.destroyed) { \
|
|
||||||
QScopedPointer<TYPE > x(new TYPE); \
|
|
||||||
INITIALIZER; \
|
|
||||||
if (this__StaticVar_.pointer.testAndSetOrdered(nullptr, x.data())) { \
|
|
||||||
static QGlobalStaticDeleter<TYPE > cleanup(this__StaticVar_); \
|
|
||||||
x.take(); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
return this__StaticVar_.pointer; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // QT_NO_THREAD
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Utility macros and inline functions
|
Utility macros and inline functions
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,25 +24,6 @@ QT_BEGIN_NAMESPACE
|
||||||
arraytype arrayname[arraysize]; \
|
arraytype arrayname[arraysize]; \
|
||||||
::memset(arrayname, 0, arraysize * sizeof(arraytype));
|
::memset(arrayname, 0, arraysize * sizeof(arraytype));
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class QThreadLocalDeleter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
T* threadLocal;
|
|
||||||
QThreadLocalDeleter(T* _threadLocal)
|
|
||||||
: threadLocal(_threadLocal)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
inline ~QThreadLocalDeleter()
|
|
||||||
{
|
|
||||||
delete threadLocal;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#define QTHREADLOCAL(localtype, localname) \
|
|
||||||
thread_local localtype* localname(nullptr); \
|
|
||||||
thread_local QThreadLocalDeleter<localtype> localname## _deleter(localname);
|
|
||||||
|
|
||||||
static const qreal q_deg2rad = qreal(0.01745329251994329576923690768489); /* pi/180 */
|
static const qreal q_deg2rad = qreal(0.01745329251994329576923690768489); /* pi/180 */
|
||||||
static const qreal q_rad2deg = qreal(57.295779513082320876798154814105); /* 180/pi */
|
static const qreal q_rad2deg = qreal(57.295779513082320876798154814105); /* 180/pi */
|
||||||
|
|
||||||
|
|
|
@ -99,17 +99,21 @@ Qt::BrushStyle BrushPropertyManager::brushStyleIndexToStyle(int brushStyleIndex)
|
||||||
return Qt::NoBrush;
|
return Qt::NoBrush;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef QMap<int, QIcon> EnumIndexIconMap;
|
typedef QMap<int, QIcon> EnumIndexIconMap;
|
||||||
|
Q_GLOBAL_STATIC(EnumIndexIconMap, brushIcons)
|
||||||
static void clearBrushIcons();
|
|
||||||
Q_GLOBAL_STATIC_WITH_INITIALIZER(EnumIndexIconMap, brushIcons, qAddPostRoutine(clearBrushIcons))
|
|
||||||
|
|
||||||
static void clearBrushIcons()
|
static void clearBrushIcons()
|
||||||
{
|
{
|
||||||
brushIcons()->clear();
|
brushIcons()->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int brushIconsCleanup()
|
||||||
|
{
|
||||||
|
qAddPostRoutine(clearBrushIcons);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Q_CONSTRUCTOR_FUNCTION(brushIconsCleanup)
|
||||||
|
|
||||||
const BrushPropertyManager::EnumIndexIconMap &BrushPropertyManager::brushStyleIcons()
|
const BrushPropertyManager::EnumIndexIconMap &BrushPropertyManager::brushStyleIcons()
|
||||||
{
|
{
|
||||||
// Create a map of icons for the brush style editor
|
// Create a map of icons for the brush style editor
|
||||||
|
|
|
@ -138,7 +138,7 @@
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
QTHREADLOCAL(QUnifiedTimer, unifiedTimer);
|
thread_local std::unique_ptr<QUnifiedTimer> unifiedTimer(nullptr);
|
||||||
|
|
||||||
QUnifiedTimer::QUnifiedTimer() :
|
QUnifiedTimer::QUnifiedTimer() :
|
||||||
QObject(), lastTick(0), currentAnimationIdx(0), insideTick(false),
|
QObject(), lastTick(0), currentAnimationIdx(0), insideTick(false),
|
||||||
|
@ -152,9 +152,9 @@ QUnifiedTimer::QUnifiedTimer() :
|
||||||
QUnifiedTimer *QUnifiedTimer::instance()
|
QUnifiedTimer *QUnifiedTimer::instance()
|
||||||
{
|
{
|
||||||
if (!unifiedTimer) {
|
if (!unifiedTimer) {
|
||||||
unifiedTimer = new QUnifiedTimer;
|
unifiedTimer = std::make_unique<QUnifiedTimer>();
|
||||||
}
|
}
|
||||||
return unifiedTimer;
|
return unifiedTimer.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QUnifiedTimer::ensureTimerUpdate()
|
void QUnifiedTimer::ensureTimerUpdate()
|
||||||
|
@ -273,7 +273,7 @@ void QUnifiedTimer::unregisterAnimation(QAbstractAnimation *animation)
|
||||||
--unifiedTimer->currentAnimationIdx;
|
--unifiedTimer->currentAnimationIdx;
|
||||||
|
|
||||||
if (unifiedTimer->animations.isEmpty() && !unifiedTimer->startStopAnimationTimer.isActive())
|
if (unifiedTimer->animations.isEmpty() && !unifiedTimer->startStopAnimationTimer.isActive())
|
||||||
unifiedTimer->startStopAnimationTimer.start(STARTSTOP_TIMER_DELAY, unifiedTimer);
|
unifiedTimer->startStopAnimationTimer.start(STARTSTOP_TIMER_DELAY, unifiedTimer.get());
|
||||||
} else {
|
} else {
|
||||||
unifiedTimer->animationsToStart.removeOne(animation);
|
unifiedTimer->animationsToStart.removeOne(animation);
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,10 +115,9 @@ public:
|
||||||
|
|
||||||
class Q_GUI_EXPORT QUnifiedTimer : public QObject
|
class Q_GUI_EXPORT QUnifiedTimer : public QObject
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
QUnifiedTimer();
|
QUnifiedTimer();
|
||||||
|
|
||||||
public:
|
|
||||||
//XXX this is needed by dui
|
//XXX this is needed by dui
|
||||||
static QUnifiedTimer *instance();
|
static QUnifiedTimer *instance();
|
||||||
|
|
||||||
|
|
|
@ -1614,14 +1614,14 @@ bool QFontInfo::exactMatch() const
|
||||||
|
|
||||||
// **********************************************************************
|
// **********************************************************************
|
||||||
// QFontCache
|
// QFontCache
|
||||||
QTHREADLOCAL(QFontCache, theFontCache);
|
thread_local std::unique_ptr<QFontCache> theFontCache(nullptr);
|
||||||
|
|
||||||
QFontCache *QFontCache::instance()
|
QFontCache *QFontCache::instance()
|
||||||
{
|
{
|
||||||
if (!theFontCache) {
|
if (!theFontCache) {
|
||||||
theFontCache = new QFontCache();
|
theFontCache = std::make_unique<QFontCache>();
|
||||||
}
|
}
|
||||||
return theFontCache;
|
return theFontCache.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
QFontCache::QFontCache()
|
QFontCache::QFontCache()
|
||||||
|
|
|
@ -6276,16 +6276,22 @@ void QtColorPropertyManager::uninitializeProperty(QtProperty *property)
|
||||||
|
|
||||||
// QtCursorPropertyManager
|
// QtCursorPropertyManager
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC(QtCursorDatabase, propertyCursorDatabase)
|
||||||
|
|
||||||
// Make sure icons are removed as soon as QApplication is destroyed, otherwise,
|
// Make sure icons are removed as soon as QApplication is destroyed, otherwise,
|
||||||
// handles are leaked on X11.
|
// handles are leaked on X11.
|
||||||
static void clearCursorDatabase();
|
|
||||||
Q_GLOBAL_STATIC_WITH_INITIALIZER(QtCursorDatabase, propertyCursorDatabase, qAddPostRoutine(clearCursorDatabase))
|
|
||||||
|
|
||||||
static void clearCursorDatabase()
|
static void clearCursorDatabase()
|
||||||
{
|
{
|
||||||
propertyCursorDatabase()->clear();
|
propertyCursorDatabase()->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int propertyCursorDatabaseCleanup()
|
||||||
|
{
|
||||||
|
qAddPostRoutine(clearCursorDatabase);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Q_CONSTRUCTOR_FUNCTION(propertyCursorDatabaseCleanup)
|
||||||
|
|
||||||
class QtCursorPropertyManagerPrivate
|
class QtCursorPropertyManagerPrivate
|
||||||
{
|
{
|
||||||
QtCursorPropertyManager *q_ptr;
|
QtCursorPropertyManager *q_ptr;
|
||||||
|
|
Loading…
Add table
Reference in a new issue