summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@trolltech.com>2009-06-03 18:47:06 (GMT)
committerOlivier Goffart <ogoffart@trolltech.com>2009-06-10 12:58:25 (GMT)
commit1a5e7171b9da383ca5f6be92b7cb6e502fd79fc4 (patch)
tree99484f1f745cea1bfa2bc4597788b2996faf89e8
parenta66525c2e4c760f8ceda344cd7252431ed263654 (diff)
downloadQt-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.cpp22
-rw-r--r--src/corelib/kernel/qobject.h3
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;
};