OSDN Git Service

get rid of the subject to race condition Q_GLOBAL_STATIC_WITH_INITIALIZER() macro...
authorIvailo Monev <xakepa10@gmail.com>
Tue, 25 Jan 2022 13:51:33 +0000 (15:51 +0200)
committerIvailo Monev <xakepa10@gmail.com>
Tue, 25 Jan 2022 15:42:18 +0000 (17:42 +0200)
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
14 files changed:
CMakeLists.txt
package/freebsd/pkg-plist
package/netbsd/PLIST
package/openbsd/pkg/PLIST
scripts/incfsck.py
scripts/namefsck.py
src/core/global/qglobal.cpp
src/core/global/qglobal.h
src/core/qcorecommon_p.h
src/designer/components/propertyeditor/brushpropertymanager.cpp
src/gui/animation/qabstractanimation.cpp
src/gui/animation/qabstractanimation_p.h
src/gui/text/qfont.cpp
src/shared/qtpropertybrowser/qtpropertymanager.cpp

index 42f5a00..119813b 100644 (file)
@@ -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)
index de2fe70..5c87972 100644 (file)
@@ -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
index cec99cc..2e26def 100644 (file)
@@ -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
index 3739ead..5e79271 100644 (file)
@@ -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
index 250da67..3c5666a 100755 (executable)
@@ -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',
index ddf63f7..1a4df2f 100755 (executable)
@@ -261,8 +261,6 @@ classlist = [
     "QGenericArgument",
     "QGenericMatrix",
     "QGenericReturnArgument",
-    "QGlobalStatic",
-    "QGlobalStaticDeleter",
     "QGradient",
     "QGradientStop",
     "QGradientStops",
index 829ca3c..a8e7257 100644 (file)
@@ -1728,25 +1728,6 @@ bool QInternal::activateCallbacks(void **parameters)
 */
 
 /*!
-    \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
 
index 6e33313..5922d82 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <utility> // std::swap
 #include <cstdint> // std::uintptr_t
+#include <memory> // 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 <typename T>
-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<TYPE > thisGlobalStatic(&thisVariable); \
-        return thisGlobalStatic.pointer;                             \
-    }
-
-#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS)                  \
-    static TYPE *NAME()                                              \
-    {                                                                \
-        static TYPE thisVariable ARGS;                               \
-        static QGlobalStatic<TYPE > thisGlobalStatic(&thisVariable); \
-        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(TYPE, NAME)                              \
+    static TYPE *NAME()                                          \
+    {                                                            \
+        static std::unique_ptr<TYPE> this__StaticVar_(new TYPE); \
+        return this__StaticVar_.get();                           \
     }
 
-#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_ARGS(TYPE, NAME, ARGS)                   \
+    static TYPE *NAME()                                               \
+    {                                                                 \
+        static std::unique_ptr<TYPE> this__StaticVar_(new TYPE ARGS); \
+        return this__StaticVar_.get();                                \
     }
 
-#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
 */
index f39a906..162b331 100644 (file)
@@ -24,25 +24,6 @@ QT_BEGIN_NAMESPACE
     arraytype arrayname[arraysize]; \
     ::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_rad2deg = qreal(57.295779513082320876798154814105); /* 180/pi */
 
index 38730c5..52b083f 100644 (file)
@@ -99,17 +99,21 @@ Qt::BrushStyle BrushPropertyManager::brushStyleIndexToStyle(int brushStyleIndex)
     return Qt::NoBrush;
 }
 
-
 typedef QMap<int, QIcon> 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
index 0268fc7..a40774a 100644 (file)
 
 QT_BEGIN_NAMESPACE
 
-QTHREADLOCAL(QUnifiedTimer, unifiedTimer);
+thread_local std::unique_ptr<QUnifiedTimer> 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<QUnifiedTimer>();
     }
-    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);
         }
index c9df889..d451dd4 100644 (file)
@@ -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();
 
index c1c7662..2fe4113 100644 (file)
@@ -1614,14 +1614,14 @@ bool QFontInfo::exactMatch() const
 
 // **********************************************************************
 // QFontCache
-QTHREADLOCAL(QFontCache, theFontCache);
+thread_local std::unique_ptr<QFontCache> theFontCache(nullptr);
 
 QFontCache *QFontCache::instance()
 {
     if (!theFontCache) {
-        theFontCache = new QFontCache();
+        theFontCache = std::make_unique<QFontCache>();
     }
-    return theFontCache;
+    return theFontCache.get();
 }
 
 QFontCache::QFontCache()
index 27e85b9..b02065d 100644 (file)
@@ -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;