diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2012-02-24 18:44:17 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-01-22 17:15:58 +0100 |
commit | f7eff7251786186ca895c8fc537b304bc89977b3 (patch) | |
tree | 161dd1a09188b8d3b61a5fd2dafbf43764d8424e /src/corelib/global/qglobal.h | |
parent | 326a5e0bca9e77ce9d6a93e301c6b52a56278453 (diff) |
Add a new Q_GLOBAL_STATIC implementation
Unlike the previous implementation, this implementation is locked:
only one initialisation is ever run at the same time. It is
exception-safe, meaning that a throwing constructor will restart the
process.
Also, start using the thread-safe behaviour that GCC has offered for a
long time and C++11 requires.
Change-Id: I20db44f57d258923df64c0051358fd0d9a5ccd51
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Reviewed-by: David Faure (KDE) <faure@kde.org>
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com>
Diffstat (limited to 'src/corelib/global/qglobal.h')
-rw-r--r-- | src/corelib/global/qglobal.h | 122 |
1 files changed, 3 insertions, 119 deletions
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 03cd3dc591..60b6e32522 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -664,125 +664,6 @@ typedef void (*QFunctionPointer)(); # define Q_UNIMPLEMENTED() qWarning("%s:%d: %s: Unimplemented code.", __FILE__, __LINE__, Q_FUNC_INFO) #endif -#if defined(QT_NO_THREAD) - -template <typename T> -class QGlobalStatic -{ -public: - T *pointer; - inline QGlobalStatic(T *p) : pointer(p) { } - inline ~QGlobalStatic() { pointer = 0; } -}; - -#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(0); \ - if (!thisGlobalStatic.pointer) { \ - TYPE *x = thisGlobalStatic.pointer = &thisVariable; \ - INITIALIZER; \ - } \ - return thisGlobalStatic.pointer; \ - } - -#else - -// forward declaration, since qatomic.h needs qglobal.h -template <typename T> class QBasicAtomicPointer; - -// POD for Q_GLOBAL_STATIC -template <typename T> -class QGlobalStatic -{ -public: - QBasicAtomicPointer<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.load(); - globalStatic.pointer.store(0); - globalStatic.destroyed = true; - } -}; - -#define Q_GLOBAL_STATIC(TYPE, NAME) \ - static TYPE *NAME() \ - { \ - static QGlobalStatic<TYPE > thisGlobalStatic \ - = { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \ - if (!thisGlobalStatic.pointer.load() && !thisGlobalStatic.destroyed) { \ - TYPE *x = new TYPE; \ - if (!thisGlobalStatic.pointer.testAndSetOrdered(0, x)) \ - delete x; \ - else \ - static QGlobalStaticDeleter<TYPE > cleanup(thisGlobalStatic); \ - } \ - return thisGlobalStatic.pointer.load(); \ - } - -#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \ - static TYPE *NAME() \ - { \ - static QGlobalStatic<TYPE > thisGlobalStatic \ - = { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \ - if (!thisGlobalStatic.pointer.load() && !thisGlobalStatic.destroyed) { \ - TYPE *x = new TYPE ARGS; \ - if (!thisGlobalStatic.pointer.testAndSetOrdered(0, x)) \ - delete x; \ - else \ - static QGlobalStaticDeleter<TYPE > cleanup(thisGlobalStatic); \ - } \ - return thisGlobalStatic.pointer.load(); \ - } - -#define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER) \ - static TYPE *NAME() \ - { \ - static QGlobalStatic<TYPE > thisGlobalStatic \ - = { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \ - if (!thisGlobalStatic.pointer.load() && !thisGlobalStatic.destroyed) { \ - QScopedPointer<TYPE > x(new TYPE); \ - INITIALIZER; \ - if (thisGlobalStatic.pointer.testAndSetOrdered(0, x.data())) { \ - static QGlobalStaticDeleter<TYPE > cleanup(thisGlobalStatic); \ - x.take(); \ - } \ - } \ - return thisGlobalStatic.pointer.load(); \ - } - -#endif - Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(double p1, double p2) { return (qAbs(p1 - p2) <= 0.000000000001 * qMin(qAbs(p1), qAbs(p2))); @@ -1089,6 +970,9 @@ template <typename T> struct QEnableIf<true, T> { typedef T Type; }; QT_END_NAMESPACE QT_END_HEADER +// Q_GLOBAL_STATIC +#include <QtCore/qglobalstatic.h> + // qDebug and friends #include <QtCore/qlogging.h> #include <QtCore/qflags.h> |