diff options
author | Olivier Goffart <ogoffart@trolltech.com> | 2009-06-03 18:47:06 (GMT) |
---|---|---|
committer | Olivier Goffart <ogoffart@trolltech.com> | 2009-06-10 12:58:25 (GMT) |
commit | 1a5e7171b9da383ca5f6be92b7cb6e502fd79fc4 (patch) | |
tree | 99484f1f745cea1bfa2bc4597788b2996faf89e8 | |
parent | a66525c2e4c760f8ceda344cd7252431ed263654 (diff) | |
download | Qt-1a5e7171b9da383ca5f6be92b7cb6e502fd79fc4.zip Qt-1a5e7171b9da383ca5f6be92b7cb6e502fd79fc4.tar.gz Qt-1a5e7171b9da383ca5f6be92b7cb6e502fd79fc4.tar.bz2 |
Avoid locking and search on the global hash if there is no QPointer
As less than 10% of the object have QPointers, we can avoid locking if
we know there is no QPointer. And keeping track of which object has a
QPointer is easy.
Reviewed-by: Brad
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 22 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.h | 3 |
2 files changed, 21 insertions, 4 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index e953bcb..a095e0a 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -143,6 +143,7 @@ QObjectPrivate::QObjectPrivate(int version) inEventHandler = false; inThreadChangeEvent = false; deleteWatch = 0; + hasGuards = false; } QObjectPrivate::~QObjectPrivate() @@ -359,6 +360,7 @@ void QMetaObject::addGuard(QObject **ptr) return; } QMutexLocker locker(guardHashLock()); + QObjectPrivate::get(*ptr)->hasGuards = true; hash->insert(*ptr, ptr); } @@ -374,12 +376,17 @@ void QMetaObject::removeGuard(QObject **ptr) QMutexLocker locker(guardHashLock()); 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) { - (void) hash->erase(it); + it = hash->erase(it); + if (!more) more = (it != end && it.key() == *ptr); break; } + more = true; } + if (!more) + QObjectPrivate::get(*ptr)->hasGuards = false; } /*!\internal @@ -393,24 +400,33 @@ void QMetaObject::changeGuard(QObject **ptr, QObject *o) } QMutexLocker locker(guardHashLock()); 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) { - (void) hash->erase(it); + it = hash->erase(it); + if (!more) more = (it != end && it.key() == *ptr); break; } + more = true; } + if (!more) + QObjectPrivate::get(*ptr)->hasGuards = false; } *ptr = o; - if (*ptr) + if (*ptr) { hash->insert(*ptr, ptr); + QObjectPrivate::get(*ptr)->hasGuards = true; + } } /*! \internal */ void QObjectPrivate::clearGuards(QObject *object) { + if (!QObjectPrivate::get(object)->hasGuards) + return; GuardHash *hash = guardHash(); if (hash) { QMutexLocker locker(guardHashLock()); diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index dbec0a6..b1f41ad 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -106,7 +106,8 @@ public: uint receiveChildEvents : 1; uint inEventHandler : 1; uint inThreadChangeEvent : 1; - uint unused : 23; + uint hasGuards : 1; //true iff there is one or more QPointer attached to this object + uint unused : 22; int postedEvents; }; |