summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qglobal.h
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2012-02-24 18:44:17 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-01-22 17:15:58 +0100
commitf7eff7251786186ca895c8fc537b304bc89977b3 (patch)
tree161dd1a09188b8d3b61a5fd2dafbf43764d8424e /src/corelib/global/qglobal.h
parent326a5e0bca9e77ce9d6a93e301c6b52a56278453 (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.h122
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>