summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2009-06-10 13:29:09 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2009-06-10 13:29:09 (GMT)
commit9683cf068c3f933f836dc2a5b4a19b1c2f86d38a (patch)
tree454bd63232cb2e67a17519a4df30d5db20a0f7a9 /src/corelib/kernel
parent3bd53464371aed9c655f39d096665f9e4875ea20 (diff)
parent1a5e7171b9da383ca5f6be92b7cb6e502fd79fc4 (diff)
downloadQt-9683cf068c3f933f836dc2a5b4a19b1c2f86d38a.zip
Qt-9683cf068c3f933f836dc2a5b4a19b1c2f86d38a.tar.gz
Qt-9683cf068c3f933f836dc2a5b4a19b1c2f86d38a.tar.bz2
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qobject.cpp89
-rw-r--r--src/corelib/kernel/qobject.h3
-rw-r--r--src/corelib/kernel/qobject_p.h5
-rw-r--r--src/corelib/kernel/qtimer.cpp2
-rw-r--r--src/corelib/kernel/qvariant.cpp2
5 files changed, 63 insertions, 38 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 5e33a71..a095e0a 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -123,7 +123,7 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
}
QObjectPrivate::QObjectPrivate(int version)
- : threadData(0), currentSender(0), currentChildBeingDeleted(0), connectionLists(0)
+ : threadData(0), currentSender(0), currentChildBeingDeleted(0), connectionLists(0), senders(0)
{
if (version != QObjectPrivateVersion)
qFatal("Cannot mix incompatible Qt libraries");
@@ -143,6 +143,7 @@ QObjectPrivate::QObjectPrivate(int version)
inEventHandler = false;
inThreadChangeEvent = false;
deleteWatch = 0;
+ hasGuards = false;
}
QObjectPrivate::~QObjectPrivate()
@@ -287,8 +288,8 @@ QObjectList QObjectPrivate::senderList() const
{
QObjectList returnValue;
QMutexLocker locker(signalSlotLock(q_func()));
- for (int i = 0; i < senders.count(); ++i)
- returnValue << senders.at(i)->sender;
+ for (Connection *c = senders; c; c = c->next)
+ returnValue << c->sender;
return returnValue;
}
@@ -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());
@@ -756,8 +772,10 @@ QObject::~QObject()
QMutex *m = signalSlotLock(c->receiver);
bool needToUnlock = QOrderedMutexLocker::relock(locker.mutex(), m);
c = connectionList[i];
- if (c->receiver)
- c->receiver->d_func()->senders.removeOne(c);
+ if (c->receiver) {
+ *c->prev = c->next;
+ if (c->next) c->next->prev = c->prev;
+ }
if (needToUnlock)
m->unlock();
@@ -774,29 +792,25 @@ QObject::~QObject()
}
// disconnect all senders
- for (int i = 0; i < d->senders.count(); ) {
- QObjectPrivate::Connection *s = d->senders[i];
-
- QMutex *m = signalSlotLock(s->sender);
+ QObjectPrivate::Connection *node = d->senders;
+ while (node) {
+ QMutex *m = signalSlotLock(node->sender);
+ node->prev = &node;
bool needToUnlock = QOrderedMutexLocker::relock(locker.mutex(), m);
- if (m < locker.mutex()) {
- if (i >= d->senders.count() || s != d->senders[i]) {
- if (needToUnlock)
- m->unlock();
- continue;
- }
+ //the node has maybe been removed while the mutex was unlocked in relock?
+ if (!node || signalSlotLock(node->sender) != m) {
+ m->unlock();
+ continue;
}
- s->receiver = 0;
- QObjectConnectionListVector *senderLists = s->sender->d_func()->connectionLists;
+ node->receiver = 0;
+ QObjectConnectionListVector *senderLists = node->sender->d_func()->connectionLists;
if (senderLists)
senderLists->dirty = true;
if (needToUnlock)
m->unlock();
- ++i;
+ node = node->next;
}
-
- d->senders.clear();
}
if (d->pendTimer) {
@@ -2281,8 +2295,8 @@ QObject *QObject::sender() const
// Return 0 if d->currentSender isn't in d->senders
bool found = false;
- for (int i = 0; !found && i < d->senders.count(); ++i)
- found = (d->senders.at(i)->sender == d->currentSender->sender);
+ for (QObjectPrivate::Connection *c = d->senders; c && !found; c = c->next)
+ found = (c->sender == d->currentSender->sender);
if (!found)
return 0;
return d->currentSender->sender;
@@ -2799,9 +2813,13 @@ bool QMetaObject::connect(const QObject *sender, int signal_index,
c->method = method_index;
c->connectionType = type;
c->argumentTypes = types;
+ c->prev = &r->d_func()->senders;
+ c->next = *c->prev;
+ *c->prev = c;
+ if (c->next)
+ c->next->prev = &c->next;
s->d_func()->addConnection(signal_index, c);
- r->d_func()->senders.append(c);
if (signal_index < 0)
sender->d_func()->connectedSignals = ~0u;
@@ -2851,8 +2869,10 @@ bool QMetaObject::disconnect(const QObject *sender, int signal_index,
needToUnlock = QOrderedMutexLocker::relock(senderMutex, m);
c = connectionList[i];
}
- if (c->receiver)
- c->receiver->d_func()->senders.removeOne(c);
+ if (c->receiver) {
+ *c->prev = c->next;
+ if (c->next) c->next->prev = c->prev;
+ }
if (needToUnlock)
m->unlock();
@@ -2878,8 +2898,10 @@ bool QMetaObject::disconnect(const QObject *sender, int signal_index,
needToUnlock = QOrderedMutexLocker::relock(senderMutex, m);
c = connectionList[i];
}
- if (c->receiver)
- c->receiver->d_func()->senders.removeOne(c);
+ if (c->receiver) {
+ *c->prev = c->next;
+ if (c->next) c->next->prev = c->prev;
+ }
if (needToUnlock)
m->unlock();
@@ -3417,9 +3439,8 @@ void QObject::dumpObjectInfo()
// now look for connections where this object is the receiver
qDebug(" SIGNALS IN");
- if (!d->senders.isEmpty()) {
- for (int i = 0; i < d->senders.count(); ++i) {
- const QObjectPrivate::Connection *s = d->senders.at(i);
+ if (d->senders) {
+ for (QObjectPrivate::Connection *s = d->senders; s; s = s->next)
const QMetaMethod slot = metaObject()->method(s->method);
qDebug(" <-- %s::%s %s",
s->sender->metaObject()->className(),
@@ -3427,7 +3448,7 @@ void QObject::dumpObjectInfo()
slot.signature());
}
} else {
- qDebug(" <None>");
+ qDebug(" <None>");
}
#endif
}
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;
};
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 96d79af..d699061 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -152,6 +152,9 @@ public:
int method;
uint connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking
QBasicAtomicPointer<int> argumentTypes;
+ //senders linked list
+ Connection *next;
+ Connection **prev;
~Connection();
};
typedef QList<Connection *> ConnectionList;
@@ -160,7 +163,7 @@ public:
void addConnection(int signal, Connection *c);
void cleanConnectionLists();
- ConnectionList senders;
+ Connection *senders; //linked list;
static Sender *setCurrentSender(QObject *receiver,
Sender *sender);
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index 8ca53b9..29bdf7e 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -251,7 +251,7 @@ void QTimer::stop()
/*!
- \reimp
+ \reimp
*/
void QTimer::timerEvent(QTimerEvent *e)
{
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 2ff9818..e6f1c48 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1823,7 +1823,7 @@ QVariant::Type QVariant::nameToType(const char *name)
#ifndef QT_NO_DATASTREAM
enum { MapFromThreeCount = 35 };
-static const uint map_from_three[MapFromThreeCount] =
+static const ushort map_from_three[MapFromThreeCount] =
{
QVariant::Invalid,
QVariant::Map,