diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-07-17 07:04:08 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-07-17 07:04:51 (GMT) |
commit | 4031c0f0613090d70cd1fcacfc5b8316b12eb14e (patch) | |
tree | 56f0756ac1de431b5c19d6a59fb0f10538df676e | |
parent | 065d6dcc16d5b48b875ebe9bd755b1c605f86d89 (diff) | |
download | Qt-4031c0f0613090d70cd1fcacfc5b8316b12eb14e.zip Qt-4031c0f0613090d70cd1fcacfc5b8316b12eb14e.tar.gz Qt-4031c0f0613090d70cd1fcacfc5b8316b12eb14e.tar.bz2 |
Add non-threadsafe QGuard class
-rw-r--r-- | examples/declarative/snow/pics/loading.png | bin | 0 -> 761 bytes | |||
-rw-r--r-- | src/corelib/kernel/kernel.pri | 6 | ||||
-rw-r--r-- | src/corelib/kernel/qguard.cpp | 26 | ||||
-rw-r--r-- | src/corelib/kernel/qguard_p.h | 151 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 18 | ||||
-rw-r--r-- | src/corelib/kernel/qobject_p.h | 2 |
6 files changed, 200 insertions, 3 deletions
diff --git a/examples/declarative/snow/pics/loading.png b/examples/declarative/snow/pics/loading.png Binary files differnew file mode 100644 index 0000000..0296cfe --- /dev/null +++ b/examples/declarative/snow/pics/loading.png diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index f31794d..d71a22a 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -33,7 +33,8 @@ HEADERS += \ kernel/qsystemsemaphore.h \ kernel/qsystemsemaphore_p.h \ kernel/qfunctions_p.h \ - kernel/qmetaobjectbuilder_p.h + kernel/qmetaobjectbuilder_p.h \ + kernel/qguard_p.h SOURCES += \ kernel/qabstracteventdispatcher.cpp \ @@ -56,7 +57,8 @@ SOURCES += \ kernel/qsharedmemory.cpp \ kernel/qsystemsemaphore.cpp \ kernel/qmetaobjectbuilder.cpp \ - kernel/qpointer.cpp + kernel/qpointer.cpp \ + kernel/qguard.cpp win32 { SOURCES += \ diff --git a/src/corelib/kernel/qguard.cpp b/src/corelib/kernel/qguard.cpp new file mode 100644 index 0000000..c61be00 --- /dev/null +++ b/src/corelib/kernel/qguard.cpp @@ -0,0 +1,26 @@ +#include "qguard_p.h" +#include <private/qobject_p.h> + +void q_guard_addGuard(QGuard<QObject> *g) +{ + QObjectPrivate *p = QObjectPrivate::get(g->o); + if (p->wasDeleted) { + qWarning("QGuard: cannot add guard to deleted object"); + g->o = 0; + return; + } + + g->next = p->objectGuards; + p->objectGuards = g; + g->prev = &p->objectGuards; + if (g->next) + g->next->prev = &g->next; +} + +void q_guard_removeGuard(QGuard<QObject> *g) +{ + *g->prev = g->next; + g->next = 0; + g->prev = 0; +} + diff --git a/src/corelib/kernel/qguard_p.h b/src/corelib/kernel/qguard_p.h new file mode 100644 index 0000000..7236ed6 --- /dev/null +++ b/src/corelib/kernel/qguard_p.h @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGUARD_P_H +#define QGUARD_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include "QtCore/qglobal.h" + +QT_BEGIN_NAMESPACE + +class QObject; +template<class T> +class QGuard +{ + QObject *o; + QGuard<QObject> *next; + QGuard<QObject> **prev; + friend void q_guard_addGuard(QGuard<QObject> *); + friend void q_guard_removeGuard(QGuard<QObject> *); + friend class QObjectPrivate; +public: + inline QGuard(); + inline QGuard(T *); + inline QGuard(const QGuard<T> &); + inline virtual ~QGuard(); + + inline QGuard<T> &operator=(const QGuard<T> &o); + inline QGuard<T> &operator=(T *); + + inline bool isNull() const + { return !o; } + + inline T* operator->() const + { return static_cast<T*>(const_cast<QObject*>(o)); } + inline T& operator*() const + { return *static_cast<T*>(const_cast<QObject*>(o)); } + inline operator T*() const + { return static_cast<T*>(const_cast<QObject*>(o)); } + inline T* data() const + { return static_cast<T*>(const_cast<QObject*>(o)); } + +protected: + virtual void objectDestroyed(T *) {} +}; + +void Q_CORE_EXPORT q_guard_addGuard(QGuard<QObject> *); +void Q_CORE_EXPORT q_guard_removeGuard(QGuard<QObject> *); + +template<class T> +QGuard<T>::QGuard() +: o(0), next(0), prev(0) +{ +} + +template<class T> +QGuard<T>::QGuard(T *g) +: o(g), next(0), prev(0) +{ + if (o) q_guard_addGuard(reinterpret_cast<QGuard<QObject> *>(this)); +} + +template<class T> +QGuard<T>::QGuard(const QGuard<T> &g) +: o(g.o), next(0), prev(0) +{ + if (o) q_guard_addGuard(reinterpret_cast<QGuard<QObject> *>(this)); +} + +template<class T> +QGuard<T>::~QGuard() +{ + if (prev) q_guard_removeGuard(reinterpret_cast<QGuard<QObject> *>(this)); + o = 0; +} + +template<class T> +QGuard<T> &QGuard<T>::operator=(const QGuard<T> &g) +{ + if (g.o != o) { + if (prev) + q_guard_removeGuard(reinterpret_cast<QGuard<QObject> *>(this)); + o = g.o; + if (o) q_guard_addGuard(reinterpret_cast<QGuard<QObject> *>(this)); + } + return *this; +} + +template<class T> +inline QGuard<T> &QGuard<T>::operator=(T *g) +{ + if (g != o) { + if (prev) + q_guard_removeGuard(reinterpret_cast<QGuard<QObject> *>(this)); + o = g; + if (o) q_guard_addGuard(reinterpret_cast<QGuard<QObject> *>(this)); + } + return *this; +} + +QT_END_NAMESPACE + +#endif // QGUARD_P_H diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 1742cd0..8517897 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -144,6 +144,7 @@ QObjectPrivate::QObjectPrivate(int version) inEventHandler = false; inThreadChangeEvent = false; deleteWatch = 0; + objectGuards = 0; metaObject = 0; hasGuards = false; } @@ -428,7 +429,22 @@ void QMetaObject::changeGuard(QObject **ptr, QObject *o) */ void QObjectPrivate::clearGuards(QObject *object) { - if (!QObjectPrivate::get(object)->hasGuards) + QObjectPrivate *priv = QObjectPrivate::get(object); + QGuard<QObject> *guard = priv->objectGuards; + while (guard) { + guard->o = 0; + guard = guard->next; + } + while (priv->objectGuards) { + guard = priv->objectGuards; + guard->prev = 0; + if (guard->next) guard->next->prev = &priv->objectGuards; + priv->objectGuards = guard->next; + guard->next = 0; + guard->objectDestroyed(object); + } + + if (!priv->hasGuards) return; GuardHash *hash = guardHash(); if (hash) { diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 83239fe..4ac0d2d 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -60,6 +60,7 @@ #include "QtCore/qvector.h" #include "QtCore/qreadwritelock.h" #include "QtCore/qvariant.h" +#include "qguard_p.h" QT_BEGIN_NAMESPACE @@ -184,6 +185,7 @@ public: static void resetDeleteWatch(QObjectPrivate *d, int *oldWatch, int deleteWatch); int *deleteWatch; + QGuard<QObject> *objectGuards; static QObjectPrivate *get(QObject *o) { return o->d_func(); |