OSDN Git Service

make QPointer use QWeakPoint
authorIvailo Monev <xakepa10@laimg.moc>
Fri, 19 Aug 2016 21:10:59 +0000 (21:10 +0000)
committerIvailo Monev <xakepa10@laimg.moc>
Fri, 19 Aug 2016 21:10:59 +0000 (21:10 +0000)
upstream commits:
https://github.com/qt/qtbase/commit/6f0f9f69288925ef423c542ef5eb7302a5431867
https://github.com/qt/qtbase/commit/c21ed8ca1f03c82731abf01fc66e4c2f2e4c2a50

Signed-off-by: Ivailo Monev <xakepa10@laimg.moc>
src/core/kernel/qobject.cpp
src/core/kernel/qobject.h
src/core/kernel/qobject_p.h
src/core/kernel/qobjectdefs.h
src/core/kernel/qpointer.h
src/gui/kernel/qaction.cpp
src/gui/kernel/qwidget.cpp

index ddc9e02..5da1e76 100644 (file)
@@ -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<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,
@@ -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.");
index 8943036..51f62bd 100644 (file)
@@ -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
 };
index 9e3ee7c..4803f7f 100644 (file)
@@ -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();
index 26265b0..a46dce3 100644 (file)
@@ -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,
index 739bdf5..87cba94 100644 (file)
@@ -42,7 +42,7 @@
 #ifndef QPOINTER_H
 #define QPOINTER_H
 
-#include <QtCore/qobject.h>
+#include <QtCore/qsharedpointer.h>
 
 QT_BEGIN_HEADER
 
@@ -52,36 +52,30 @@ QT_BEGIN_NAMESPACE
 template <class T>
 class 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<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*>(o); }
+        { return wp.data(); }
     inline T& operator*() const
-        { return *static_cast<T*>(o); }
+        { return *wp.data(); }
     inline operator T*() const
-        { return static_cast<T*>(o); }
+        { return wp.data(); }
     inline T* data() const
-        { return static_cast<T*>(o); }
+        { return wp.data(); }
 };
 
 
-#if (!defined(Q_CC_SUN) || (__SUNPRO_CC >= 0x580)) // ambiguity between const T * and T *
-
 template <class T>
 inline bool operator==(const T *o, const QPointer<T> &p)
 { return o == p.operator->(); }
@@ -90,18 +84,6 @@ template<class T>
 inline bool operator==(const QPointer<T> &p, const T *o)
 { return p.operator->() == o; }
 
-#else
-
-template<class T>
-inline bool operator==(const void *o, const QPointer<T> &p)
-{ return o == p.operator->(); }
-
-template<class T>
-inline bool operator==(const QPointer<T> &p, const void *o)
-{ return p.operator->() == o; }
-
-#endif
-
 template <class T>
 inline bool operator==(T *o, const QPointer<T> &p)
 { return o == p.operator->(); }
@@ -114,9 +96,6 @@ template<class T>
 inline bool operator==(const QPointer<T> &p1, const QPointer<T> &p2)
 { return p1.operator->() == p2.operator->(); }
 
-
-#if (!defined(Q_CC_SUN) || (__SUNPRO_CC >= 0x580)) // ambiguity between const T * and T *
-
 template <class T>
 inline bool operator!=(const T *o, const QPointer<T> &p)
 { return o != p.operator->(); }
@@ -125,18 +104,6 @@ template<class T>
 inline bool operator!= (const QPointer<T> &p, const T *o)
 { return p.operator->() != o; }
 
-#else
-
-template<class T>
-inline bool operator!= (const void *o, const QPointer<T> &p)
-{ return o != p.operator->(); }
-
-template<class T>
-inline bool operator!= (const QPointer<T> &p, const void *o)
-{ return p.operator->() != o; }
-
-#endif
-
 template <class T>
 inline bool operator!=(T *o, const QPointer<T> &p)
 { return o != p.operator->(); }
@@ -149,17 +116,6 @@ template<class T>
 inline bool operator!= (const QPointer<T> &p1, const QPointer<T> &p2)
 { return p1.operator->() != p2.operator->() ; }
 
-// Make MSVC < 1400 (2005) handle "if (NULL == p)" syntax
-#if defined(Q_CC_MSVC) && (_MSC_VER < 1400)
-template<class T>
-inline bool operator== (int i, const QPointer<T> &p)
-{ Q_ASSERT(i == 0); return !i && p.isNull(); }
-
-template<class T>
-inline bool operator!= (int i, const QPointer<T> &p)
-{ Q_ASSERT(i == 0); return !i && !p.isNull(); }
-#endif
-
 QT_END_NAMESPACE
 
 QT_END_HEADER
index 09ce11c..dc23084 100644 (file)
@@ -1158,22 +1158,19 @@ void QAction::activate(ActionEvent event)
 {
     Q_D(QAction);
     if(event == Trigger) {
-        QObject *guard = this;
-        QMetaObject::addGuard(&guard);
+        QWeakPointer<QObject> 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();
     }
index 4eeaa97..a66cce0 100644 (file)
@@ -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