From 69e4c8a3ac40e3b324d06f02becb04cc09d28095 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Tue, 25 Jan 2022 15:51:33 +0200 Subject: [PATCH] get rid of the subject to race condition Q_GLOBAL_STATIC_WITH_INITIALIZER() macro [ci reset] Signed-off-by: Ivailo Monev --- CMakeLists.txt | 2 - package/freebsd/pkg-plist | 2 - package/netbsd/PLIST | 2 - package/openbsd/pkg/PLIST | 2 - scripts/incfsck.py | 2 - scripts/namefsck.py | 2 - src/core/global/qglobal.cpp | 19 --- src/core/global/qglobal.h | 116 ++---------------- src/core/qcorecommon_p.h | 19 --- .../propertyeditor/brushpropertymanager.cpp | 12 +- src/gui/animation/qabstractanimation.cpp | 8 +- src/gui/animation/qabstractanimation_p.h | 3 +- src/gui/text/qfont.cpp | 6 +- .../qtpropertybrowser/qtpropertymanager.cpp | 12 +- 14 files changed, 36 insertions(+), 171 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 42f5a0013..119813b91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -665,8 +665,6 @@ katie_generate_obsolete(QFutureIterator QtCore qfuture.h) katie_generate_obsolete(QFutureWatcherBase QtCore qfuturewatcher.h) katie_generate_obsolete(QGenericArgument 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(QGradientStop QtGui qbrush.h) katie_generate_obsolete(QGradientStops QtGui qbrush.h) diff --git a/package/freebsd/pkg-plist b/package/freebsd/pkg-plist index de2fe7094..5c8797252 100644 --- a/package/freebsd/pkg-plist +++ b/package/freebsd/pkg-plist @@ -62,8 +62,6 @@ include/katie/QtCore/QFutureWatcher include/katie/QtCore/QFutureWatcherBase include/katie/QtCore/QGenericArgument include/katie/QtCore/QGenericReturnArgument -include/katie/QtCore/QGlobalStatic -include/katie/QtCore/QGlobalStaticDeleter include/katie/QtCore/QHash include/katie/QtCore/QHashData include/katie/QtCore/QHashIterator diff --git a/package/netbsd/PLIST b/package/netbsd/PLIST index cec99cc44..2e26defa1 100644 --- a/package/netbsd/PLIST +++ b/package/netbsd/PLIST @@ -65,8 +65,6 @@ include/katie/QtCore/QFutureWatcher include/katie/QtCore/QFutureWatcherBase include/katie/QtCore/QGenericArgument include/katie/QtCore/QGenericReturnArgument -include/katie/QtCore/QGlobalStatic -include/katie/QtCore/QGlobalStaticDeleter include/katie/QtCore/QHash include/katie/QtCore/QHashData include/katie/QtCore/QHashIterator diff --git a/package/openbsd/pkg/PLIST b/package/openbsd/pkg/PLIST index 3739ead0f..5e79271a8 100644 --- a/package/openbsd/pkg/PLIST +++ b/package/openbsd/pkg/PLIST @@ -65,8 +65,6 @@ include/katie/QtCore/QFutureWatcher include/katie/QtCore/QFutureWatcherBase include/katie/QtCore/QGenericArgument include/katie/QtCore/QGenericReturnArgument -include/katie/QtCore/QGlobalStatic -include/katie/QtCore/QGlobalStaticDeleter include/katie/QtCore/QHash include/katie/QtCore/QHashData include/katie/QtCore/QHashIterator diff --git a/scripts/incfsck.py b/scripts/incfsck.py index 250da6724..3c5666a17 100755 --- a/scripts/incfsck.py +++ b/scripts/incfsck.py @@ -29,8 +29,6 @@ incmap = { 'QFutureWatcherBase': 'qfuturewatcher.h', 'QGenericArgument': 'qobjectdefs.h', 'QGenericReturnArgument': 'qobjectdefs.h', - 'QGlobalStatic': 'qglobal.h', - 'QGlobalStaticDeleter': 'qglobal.h', 'QHashData': 'qhash.h', 'QHashIterator': 'qhash.h', 'QHashNode': 'qhash.h', diff --git a/scripts/namefsck.py b/scripts/namefsck.py index ddf63f7f4..1a4df2f48 100755 --- a/scripts/namefsck.py +++ b/scripts/namefsck.py @@ -261,8 +261,6 @@ classlist = [ "QGenericArgument", "QGenericMatrix", "QGenericReturnArgument", - "QGlobalStatic", - "QGlobalStaticDeleter", "QGradient", "QGradientStop", "QGradientStops", diff --git a/src/core/global/qglobal.cpp b/src/core/global/qglobal.cpp index 829ca3c06..a8e7257e6 100644 --- a/src/core/global/qglobal.cpp +++ b/src/core/global/qglobal.cpp @@ -1727,25 +1727,6 @@ bool QInternal::activateCallbacks(void **parameters) 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 \internal diff --git a/src/core/global/qglobal.h b/src/core/global/qglobal.h index 6e333132b..5922d8294 100644 --- a/src/core/global/qglobal.h +++ b/src/core/global/qglobal.h @@ -36,6 +36,7 @@ #include // std::swap #include // std::uintptr_t +#include // std::unique_ptr typedef unsigned char uchar; 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 *); Q_CORE_EXPORT QtMsgHandler qInstallMsgHandler(QtMsgHandler); - -#if defined(QT_NO_THREAD) - -template -class QGlobalStatic -{ -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 thisGlobalStatic(&thisVariable); \ - return thisGlobalStatic.pointer; \ +#define Q_GLOBAL_STATIC(TYPE, NAME) \ + static TYPE *NAME() \ + { \ + static std::unique_ptr this__StaticVar_(new TYPE); \ + return this__StaticVar_.get(); \ } -#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \ - static TYPE *NAME() \ - { \ - static TYPE thisVariable ARGS; \ - static QGlobalStatic thisGlobalStatic(&thisVariable); \ - return thisGlobalStatic.pointer; \ +#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \ + static TYPE *NAME() \ + { \ + static std::unique_ptr this__StaticVar_(new TYPE ARGS); \ + return this__StaticVar_.get(); \ } -#define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER) \ - static TYPE *NAME() \ - { \ - static TYPE thisVariable; \ - static QGlobalStatic 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 class QAtomicPointer; - -// POD for Q_GLOBAL_STATIC -template -class QGlobalStatic -{ -public: - QAtomicPointer pointer; - bool destroyed; -}; - -// Created as a function-local static to delete a QGlobalStatic -template -class QGlobalStaticDeleter -{ -public: - QGlobalStatic &globalStatic; - QGlobalStaticDeleter(QGlobalStatic &_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 this__StaticVar_ \ - = { QAtomicPointer(new TYPE), false }; \ - static QGlobalStaticDeleter cleanup(this__StaticVar_); \ - return this__StaticVar_.pointer; \ - } - -#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \ - static TYPE *NAME() \ - { \ - static QGlobalStatic this__StaticVar_ \ - = { QAtomicPointer(new TYPE ARGS), false }; \ - static QGlobalStaticDeleter cleanup(this__StaticVar_); \ - return this__StaticVar_.pointer; \ - } - -#define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER) \ - static TYPE *NAME() \ - { \ - static QGlobalStatic this__StaticVar_ \ - = { QAtomicPointer(nullptr), false }; \ - if (!this__StaticVar_.pointer && !this__StaticVar_.destroyed) { \ - QScopedPointer x(new TYPE); \ - INITIALIZER; \ - if (this__StaticVar_.pointer.testAndSetOrdered(nullptr, x.data())) { \ - static QGlobalStaticDeleter cleanup(this__StaticVar_); \ - x.take(); \ - } \ - } \ - return this__StaticVar_.pointer; \ - } - -#endif // QT_NO_THREAD - - /* Utility macros and inline functions */ diff --git a/src/core/qcorecommon_p.h b/src/core/qcorecommon_p.h index f39a9064b..162b33175 100644 --- a/src/core/qcorecommon_p.h +++ b/src/core/qcorecommon_p.h @@ -24,25 +24,6 @@ QT_BEGIN_NAMESPACE arraytype arrayname[arraysize]; \ ::memset(arrayname, 0, arraysize * sizeof(arraytype)); -template -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 localname## _deleter(localname); - static const qreal q_deg2rad = qreal(0.01745329251994329576923690768489); /* pi/180 */ static const qreal q_rad2deg = qreal(57.295779513082320876798154814105); /* 180/pi */ diff --git a/src/designer/components/propertyeditor/brushpropertymanager.cpp b/src/designer/components/propertyeditor/brushpropertymanager.cpp index 38730c5e0..52b083f35 100644 --- a/src/designer/components/propertyeditor/brushpropertymanager.cpp +++ b/src/designer/components/propertyeditor/brushpropertymanager.cpp @@ -99,17 +99,21 @@ Qt::BrushStyle BrushPropertyManager::brushStyleIndexToStyle(int brushStyleIndex) return Qt::NoBrush; } - typedef QMap EnumIndexIconMap; - -static void clearBrushIcons(); -Q_GLOBAL_STATIC_WITH_INITIALIZER(EnumIndexIconMap, brushIcons, qAddPostRoutine(clearBrushIcons)) +Q_GLOBAL_STATIC(EnumIndexIconMap, brushIcons) static void clearBrushIcons() { brushIcons()->clear(); } +static int brushIconsCleanup() +{ + qAddPostRoutine(clearBrushIcons); + return 0; +} +Q_CONSTRUCTOR_FUNCTION(brushIconsCleanup) + const BrushPropertyManager::EnumIndexIconMap &BrushPropertyManager::brushStyleIcons() { // Create a map of icons for the brush style editor diff --git a/src/gui/animation/qabstractanimation.cpp b/src/gui/animation/qabstractanimation.cpp index 0268fc76b..a40774ac7 100644 --- a/src/gui/animation/qabstractanimation.cpp +++ b/src/gui/animation/qabstractanimation.cpp @@ -138,7 +138,7 @@ QT_BEGIN_NAMESPACE -QTHREADLOCAL(QUnifiedTimer, unifiedTimer); +thread_local std::unique_ptr unifiedTimer(nullptr); QUnifiedTimer::QUnifiedTimer() : QObject(), lastTick(0), currentAnimationIdx(0), insideTick(false), @@ -152,9 +152,9 @@ QUnifiedTimer::QUnifiedTimer() : QUnifiedTimer *QUnifiedTimer::instance() { if (!unifiedTimer) { - unifiedTimer = new QUnifiedTimer; + unifiedTimer = std::make_unique(); } - return unifiedTimer; + return unifiedTimer.get(); } void QUnifiedTimer::ensureTimerUpdate() @@ -273,7 +273,7 @@ void QUnifiedTimer::unregisterAnimation(QAbstractAnimation *animation) --unifiedTimer->currentAnimationIdx; if (unifiedTimer->animations.isEmpty() && !unifiedTimer->startStopAnimationTimer.isActive()) - unifiedTimer->startStopAnimationTimer.start(STARTSTOP_TIMER_DELAY, unifiedTimer); + unifiedTimer->startStopAnimationTimer.start(STARTSTOP_TIMER_DELAY, unifiedTimer.get()); } else { unifiedTimer->animationsToStart.removeOne(animation); } diff --git a/src/gui/animation/qabstractanimation_p.h b/src/gui/animation/qabstractanimation_p.h index c9df889e2..d451dd413 100644 --- a/src/gui/animation/qabstractanimation_p.h +++ b/src/gui/animation/qabstractanimation_p.h @@ -115,10 +115,9 @@ public: class Q_GUI_EXPORT QUnifiedTimer : public QObject { -private: +public: QUnifiedTimer(); -public: //XXX this is needed by dui static QUnifiedTimer *instance(); diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index c1c766224..2fe41138f 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -1614,14 +1614,14 @@ bool QFontInfo::exactMatch() const // ********************************************************************** // QFontCache -QTHREADLOCAL(QFontCache, theFontCache); +thread_local std::unique_ptr theFontCache(nullptr); QFontCache *QFontCache::instance() { if (!theFontCache) { - theFontCache = new QFontCache(); + theFontCache = std::make_unique(); } - return theFontCache; + return theFontCache.get(); } QFontCache::QFontCache() diff --git a/src/shared/qtpropertybrowser/qtpropertymanager.cpp b/src/shared/qtpropertybrowser/qtpropertymanager.cpp index 27e85b912..b02065da2 100644 --- a/src/shared/qtpropertybrowser/qtpropertymanager.cpp +++ b/src/shared/qtpropertybrowser/qtpropertymanager.cpp @@ -6276,16 +6276,22 @@ void QtColorPropertyManager::uninitializeProperty(QtProperty *property) // QtCursorPropertyManager +Q_GLOBAL_STATIC(QtCursorDatabase, propertyCursorDatabase) + // Make sure icons are removed as soon as QApplication is destroyed, otherwise, // handles are leaked on X11. -static void clearCursorDatabase(); -Q_GLOBAL_STATIC_WITH_INITIALIZER(QtCursorDatabase, propertyCursorDatabase, qAddPostRoutine(clearCursorDatabase)) - static void clearCursorDatabase() { propertyCursorDatabase()->clear(); } +static int propertyCursorDatabaseCleanup() +{ + qAddPostRoutine(clearCursorDatabase); + return 0; +} +Q_CONSTRUCTOR_FUNCTION(propertyCursorDatabaseCleanup) + class QtCursorPropertyManagerPrivate { QtCursorPropertyManager *q_ptr;