From: Ivailo Monev Date: Fri, 19 Aug 2016 21:10:59 +0000 (+0000) Subject: make QPointer use QWeakPoint X-Git-Tag: 4.12.0~6824 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=89e6e7775eb9b92754b7a4a47987672b691562aa;p=kde%2FKatie.git make QPointer use QWeakPoint upstream commits: https://github.com/qt/qtbase/commit/6f0f9f69288925ef423c542ef5eb7302a5431867 https://github.com/qt/qtbase/commit/c21ed8ca1f03c82731abf01fc66e4c2f2e4c2a50 Signed-off-by: Ivailo Monev --- diff --git a/src/core/kernel/qobject.cpp b/src/core/kernel/qobject.cpp index ddc9e02ef..5da1e76f3 100644 --- a/src/core/kernel/qobject.cpp +++ b/src/core/kernel/qobject.cpp @@ -151,7 +151,6 @@ QObjectPrivate::QObjectPrivate(int version) connectedSignals[0] = connectedSignals[1] = 0; inThreadChangeEvent = false; metaObject = 0; - hasGuards = false; } QObjectPrivate::~QObjectPrivate() @@ -338,113 +337,6 @@ void QObjectPrivate::cleanConnectionLists() } } -typedef QMultiHash 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, @@ -782,12 +674,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); - } - if (d->sharedRefcount) { if (d->sharedRefcount->strongref > 0) { qWarning("QObject: shared QObject was deleted directly. The program is malformed and may crash."); diff --git a/src/core/kernel/qobject.h b/src/core/kernel/qobject.h index 89430366f..51f62bd3a 100644 --- a/src/core/kernel/qobject.h +++ b/src/core/kernel/qobject.h @@ -99,7 +99,6 @@ public: uint sendChildEvents : 1; uint receiveChildEvents : 1; uint inThreadChangeEvent : 1; - uint hasGuards : 1; //true if there is one or more QPointer attached to this object int postedEvents; QMetaObject *metaObject; // assert dynamic }; diff --git a/src/core/kernel/qobject_p.h b/src/core/kernel/qobject_p.h index 9e3ee7c0c..4803f7f83 100644 --- a/src/core/kernel/qobject_p.h +++ b/src/core/kernel/qobject_p.h @@ -162,7 +162,6 @@ public: static inline void resetCurrentSender(QObject *receiver, Sender *currentSender, Sender *previousSender); - static void clearGuards(QObject *); static QObjectPrivate *get(QObject *o) { return o->d_func(); diff --git a/src/core/kernel/qobjectdefs.h b/src/core/kernel/qobjectdefs.h index 26265b078..a46dce3d1 100644 --- a/src/core/kernel/qobjectdefs.h +++ b/src/core/kernel/qobjectdefs.h @@ -342,11 +342,6 @@ struct Q_CORE_EXPORT QMetaObject static void activate(QObject *sender, int signal_index, void **argv); //obsolete 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/core/kernel/qpointer.h b/src/core/kernel/qpointer.h index 739bdf5b9..87cba94fb 100644 --- a/src/core/kernel/qpointer.h +++ b/src/core/kernel/qpointer.h @@ -42,7 +42,7 @@ #ifndef QPOINTER_H #define QPOINTER_H -#include +#include QT_BEGIN_HEADER @@ -52,36 +52,30 @@ QT_BEGIN_NAMESPACE template class QPointer { - QObject *o; + QWeakPointer wp; public: - inline QPointer() : o(0) {} - inline QPointer(T *p) : o(p) - { QMetaObject::addGuard(&o); } - inline QPointer(const QPointer &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 &p) : wp(p.wp) { } inline QPointer &operator=(const QPointer &p) - { if (this != &p) QMetaObject::changeGuard(&o, p.o); return *this; } + { wp = p.wp; return *this; } inline QPointer &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(o); } + { return wp.data(); } inline T& operator*() const - { return *static_cast(o); } + { return *wp.data(); } inline operator T*() const - { return static_cast(o); } + { return wp.data(); } inline T* data() const - { return static_cast(o); } + { return wp.data(); } }; -#if (!defined(Q_CC_SUN) || (__SUNPRO_CC >= 0x580)) // ambiguity between const T * and T * - template inline bool operator==(const T *o, const QPointer &p) { return o == p.operator->(); } @@ -90,18 +84,6 @@ template inline bool operator==(const QPointer &p, const T *o) { return p.operator->() == o; } -#else - -template -inline bool operator==(const void *o, const QPointer &p) -{ return o == p.operator->(); } - -template -inline bool operator==(const QPointer &p, const void *o) -{ return p.operator->() == o; } - -#endif - template inline bool operator==(T *o, const QPointer &p) { return o == p.operator->(); } @@ -114,9 +96,6 @@ template inline bool operator==(const QPointer &p1, const QPointer &p2) { return p1.operator->() == p2.operator->(); } - -#if (!defined(Q_CC_SUN) || (__SUNPRO_CC >= 0x580)) // ambiguity between const T * and T * - template inline bool operator!=(const T *o, const QPointer &p) { return o != p.operator->(); } @@ -125,18 +104,6 @@ template inline bool operator!= (const QPointer &p, const T *o) { return p.operator->() != o; } -#else - -template -inline bool operator!= (const void *o, const QPointer &p) -{ return o != p.operator->(); } - -template -inline bool operator!= (const QPointer &p, const void *o) -{ return p.operator->() != o; } - -#endif - template inline bool operator!=(T *o, const QPointer &p) { return o != p.operator->(); } @@ -149,17 +116,6 @@ template inline bool operator!= (const QPointer &p1, const QPointer &p2) { return p1.operator->() != p2.operator->() ; } -// Make MSVC < 1400 (2005) handle "if (NULL == p)" syntax -#if defined(Q_CC_MSVC) && (_MSC_VER < 1400) -template -inline bool operator== (int i, const QPointer &p) -{ Q_ASSERT(i == 0); return !i && p.isNull(); } - -template -inline bool operator!= (int i, const QPointer &p) -{ Q_ASSERT(i == 0); return !i && !p.isNull(); } -#endif - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp index 09ce11cf2..dc23084a3 100644 --- a/src/gui/kernel/qaction.cpp +++ b/src/gui/kernel/qaction.cpp @@ -1158,22 +1158,19 @@ void QAction::activate(ActionEvent event) { Q_D(QAction); if(event == Trigger) { - QObject *guard = this; - QMetaObject::addGuard(&guard); + QWeakPointer guard = this; if(d->checkable) { // the checked action of an exclusive group cannot be unchecked if (d->checked && (d->group && d->group->isExclusive() && d->group->checkedAction() == this)) { - if (guard) + if (!guard.isNull()) emit triggered(true); - QMetaObject::removeGuard(&guard); return; } setChecked(!d->checked); } - if (guard) + if (!guard.isNull()) emit triggered(d->checked); - QMetaObject::removeGuard(&guard); } else if(event == Hover) { emit hovered(); } diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 4eeaa979b..a66cce03b 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1516,10 +1516,6 @@ QWidget::~QWidget() delete d->needsFlush; d->needsFlush = 0; - // set all QPointers for this object to zero - if (d->hasGuards) - QObjectPrivate::clearGuards(this); - if (d->declarativeData) { QAbstractDeclarativeData::destroyed(d->declarativeData, this); d->declarativeData = 0; // don't activate again in ~QObject