summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qobject.cpp114
-rw-r--r--src/corelib/kernel/qobject.h3
-rw-r--r--src/corelib/kernel/qobject_p.h1
-rw-r--r--src/corelib/kernel/qobjectdefs.h5
-rw-r--r--src/corelib/kernel/qpointer.cpp20
-rw-r--r--src/corelib/kernel/qpointer.h37
6 files changed, 40 insertions, 140 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index f6e72e3e94..da06fc6433 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -177,7 +177,6 @@ QObjectPrivate::QObjectPrivate(int version)
deleteWatch = 0;
#endif
metaObject = 0;
- hasGuards = false;
isWindow = false;
}
@@ -409,113 +408,6 @@ void QObjectPrivate::cleanConnectionLists()
}
}
-typedef QMultiHash<QObject *, QObject **> GuardHash;
-Q_GLOBAL_STATIC(GuardHash, guardHash)
-Q_GLOBAL_STATIC(QMutex, guardHashLock)
-
-/*!\internal
- */
-void QMetaObject::addGuard(QObject **ptr)
-{
- if (!*ptr)
- return;
- GuardHash *hash = guardHash();
- if (!hash) {
- *ptr = 0;
- return;
- }
- QMutexLocker locker(guardHashLock());
- QObjectPrivate::get(*ptr)->hasGuards = true;
- hash->insert(*ptr, ptr);
-}
-
-/*!\internal
- */
-void QMetaObject::removeGuard(QObject **ptr)
-{
- if (!*ptr)
- return;
- GuardHash *hash = guardHash();
- /* check that the hash is empty - otherwise we might detach
- the shared_null hash, which will alloc, which is not nice */
- if (!hash || hash->isEmpty())
- return;
- QMutexLocker locker(guardHashLock());
- if (!*ptr) //check again, under the lock
- return;
- GuardHash::iterator it = hash->find(*ptr);
- const GuardHash::iterator end = hash->end();
- bool more = false; //if the QObject has more pointer attached to it.
- for (; it.key() == *ptr && it != end; ++it) {
- if (it.value() == ptr) {
- it = hash->erase(it);
- if (!more) more = (it != end && it.key() == *ptr);
- break;
- }
- more = true;
- }
- if (!more)
- QObjectPrivate::get(*ptr)->hasGuards = false;
-}
-
-/*!\internal
- */
-void QMetaObject::changeGuard(QObject **ptr, QObject *o)
-{
- GuardHash *hash = guardHash();
- if (!hash) {
- *ptr = 0;
- return;
- }
- QMutexLocker locker(guardHashLock());
- if (o) {
- hash->insert(o, ptr);
- QObjectPrivate::get(o)->hasGuards = true;
- }
- if (*ptr) {
- bool more = false; //if the QObject has more pointer attached to it.
- GuardHash::iterator it = hash->find(*ptr);
- const GuardHash::iterator end = hash->end();
- for (; it.key() == *ptr && it != end; ++it) {
- if (it.value() == ptr) {
- it = hash->erase(it);
- if (!more) more = (it != end && it.key() == *ptr);
- break;
- }
- more = true;
- }
- if (!more)
- QObjectPrivate::get(*ptr)->hasGuards = false;
- }
- *ptr = o;
-}
-
-/*! \internal
- */
-void QObjectPrivate::clearGuards(QObject *object)
-{
- GuardHash *hash = 0;
- QMutex *mutex = 0;
- QT_TRY {
- hash = guardHash();
- mutex = guardHashLock();
- } QT_CATCH(const std::bad_alloc &) {
- // do nothing in case of OOM - code below is safe
- }
-
- /* check that the hash is empty - otherwise we might detach
- the shared_null hash, which will alloc, which is not nice */
- if (hash && !hash->isEmpty()) {
- QMutexLocker locker(mutex);
- GuardHash::iterator it = hash->find(object);
- const GuardHash::iterator end = hash->end();
- while (it.key() == object && it != end) {
- *it.value() = 0;
- it = hash->erase(it);
- }
- }
-}
-
/*! \internal
*/
QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction,
@@ -840,12 +732,6 @@ QObject::~QObject()
d->wasDeleted = true;
d->blockSig = 0; // unblock signals so we always emit destroyed()
- if (d->hasGuards && !d->isWidget) {
- // set all QPointers for this object to zero - note that
- // ~QWidget() does this for us, so we don't have to do it twice
- QObjectPrivate::clearGuards(this);
- }
-
QtSharedPointer::ExternalRefCountData *sharedRefcount = d->sharedRefcount.load();
if (sharedRefcount) {
if (sharedRefcount->strongref.load() > 0) {
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index cc2ccb9e5b..a0d8076b73 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -105,9 +105,8 @@ public:
uint receiveChildEvents : 1;
uint inEventHandler : 1; //only used if QT_JAMBI_BUILD
uint inThreadChangeEvent : 1;
- uint hasGuards : 1; //true iff there is one or more QPointer attached to this object
uint isWindow : 1; //for QWindow
- uint unused : 21;
+ uint unused : 22;
int postedEvents;
QMetaObject *metaObject; // assert dynamic
};
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 5519a69c34..a9cac3917a 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -183,7 +183,6 @@ public:
static int *setDeleteWatch(QObjectPrivate *d, int *newWatch);
static void resetDeleteWatch(QObjectPrivate *d, int *oldWatch, int deleteWatch);
#endif
- static void clearGuards(QObject *);
static QObjectPrivate *get(QObject *o) {
return o->d_func();
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index bfb6808ad5..faadb6f48c 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -341,11 +341,6 @@ struct Q_CORE_EXPORT QMetaObject
static void activate(QObject *sender, int signal_index, void **argv);
static void activate(QObject *sender, const QMetaObject *, int local_signal_index, void **argv);
- // internal guarded pointers
- static void addGuard(QObject **ptr);
- static void removeGuard(QObject **ptr);
- static void changeGuard(QObject **ptr, QObject *o);
-
static bool invokeMethod(QObject *obj, const char *member,
Qt::ConnectionType,
QGenericReturnArgument ret,
diff --git a/src/corelib/kernel/qpointer.cpp b/src/corelib/kernel/qpointer.cpp
index c7fcf4f1e8..51c8b2ad74 100644
--- a/src/corelib/kernel/qpointer.cpp
+++ b/src/corelib/kernel/qpointer.cpp
@@ -44,7 +44,7 @@
\brief The QPointer class is a template class that provides guarded pointers to QObject.
\ingroup objectmodel
-
+ \obsolete Use QWeakPointer instead.
A guarded pointer, QPointer<T>, behaves like a normal C++
pointer \c{T *}, except that it is automatically set to 0 when the
@@ -57,6 +57,24 @@
destroyed while you still hold a reference to it. You can safely
test the pointer for validity.
+ Note that Qt 5 introduces two slight changes in behavior when using QPointer.
+
+ \list
+
+ \i When using QPointer on a QWidget (or a subclass of QWidget), previously
+ the QPointer would be cleared by the QWidget destructor. Now, the QPointer
+ is cleared by the QObject destructor (since this is when QWeakPointers are
+ cleared). Any QPointers tracking a widget will \b NOT be cleared before the
+ QWidget destructor destroys the children for the widget being tracked.
+
+ \i When constructing a QSharedPointer to take ownership of an object after a
+ QPointer is already tracking the object. Previously, the shared pointer
+ construction would not be affected by the QPointer, but now that QPointer
+ is implemented using QWeakPoiner, constructing the QSharedPointer will
+ cause an \c abort().
+
+ \endlist
+
Qt also provides QSharedPointer, an implementation of a reference-counted
shared pointer object, which can be used to maintain a collection of
references to an individual pointer.
diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h
index e9f302e317..a1d1f2037f 100644
--- a/src/corelib/kernel/qpointer.h
+++ b/src/corelib/kernel/qpointer.h
@@ -42,7 +42,7 @@
#ifndef QPOINTER_H
#define QPOINTER_H
-#include <QtCore/qobject.h>
+#include <QtCore/qsharedpointer.h>
QT_BEGIN_HEADER
@@ -50,34 +50,35 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Core)
+#if QT_DEPRECATED_SINCE(5,0)
+
template <class T>
-class QPointer
+class QT_DEPRECATED QPointer
{
- QObject *o;
+ QWeakPointer<T> wp;
+
public:
- inline QPointer() : o(0) {}
- inline QPointer(T *p) : o(p)
- { QMetaObject::addGuard(&o); }
- inline QPointer(const QPointer<T> &p) : o(p.o)
- { QMetaObject::addGuard(&o); }
- inline ~QPointer()
- { QMetaObject::removeGuard(&o); }
+ inline QPointer() : wp() { }
+ inline QPointer(T *p) : wp(p) { }
+ inline QPointer(const QPointer<T> &p) : wp(p.wp) { }
+ inline ~QPointer() { }
+
inline QPointer<T> &operator=(const QPointer<T> &p)
- { if (this != &p) QMetaObject::changeGuard(&o, p.o); return *this; }
+ { wp = p.wp; return *this; }
inline QPointer<T> &operator=(T* p)
- { if (o != p) QMetaObject::changeGuard(&o, p); return *this; }
+ { wp = p; return *this; }
inline bool isNull() const
- { return !o; }
+ { return wp.isNull(); }
inline T* operator->() const
- { return static_cast<T*>(const_cast<QObject*>(o)); }
+ { return wp.data(); }
inline T& operator*() const
- { return *static_cast<T*>(const_cast<QObject*>(o)); }
+ { return *wp.data(); }
inline operator T*() const
- { return static_cast<T*>(const_cast<QObject*>(o)); }
+ { return wp.data(); }
inline T* data() const
- { return static_cast<T*>(const_cast<QObject*>(o)); }
+ { return wp.data(); }
};
@@ -161,6 +162,8 @@ inline bool operator!= (int i, const QPointer<T> &p)
{ Q_ASSERT(i == 0); return !i && !p.isNull(); }
#endif
+#endif // QT_DEPRECATED_SINCE(5,0)
+
QT_END_NAMESPACE
QT_END_HEADER