summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <olivier.goffart@nokia.com>2010-05-26 08:05:14 (GMT)
committerOlivier Goffart <olivier.goffart@nokia.com>2010-05-28 08:21:24 (GMT)
commit66d68138c6b21d249daad27c904c688b78d21af6 (patch)
tree47b59359145d7482c26a13cc7b81d6158a56f527
parent8d267e8d7a1e3374558ed302cfa415788ca74e02 (diff)
downloadQt-66d68138c6b21d249daad27c904c688b78d21af6.zip
Qt-66d68138c6b21d249daad27c904c688b78d21af6.tar.gz
Qt-66d68138c6b21d249daad27c904c688b78d21af6.tar.bz2
Speedup destruction of QObject if the eventloop is not entered.
QObjectPrivate::removePendingChildInsertedEvents intoduce O(n^2) complexity. Remove this function and instead check the object has not been removed/reparented Known side effects: if the object would be parented multiple times to the same object, multiple QEvent::ChildInserted will be sends This would also create the QWeakPointer external refcount for almost each objects. Task-number: QTBUG-6546 Reviewed-by: Brad
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp7
-rw-r--r--src/corelib/kernel/qobject.cpp24
-rw-r--r--src/corelib/kernel/qobject_p.h4
-rw-r--r--src/gui/kernel/qapplication.cpp5
4 files changed, 5 insertions, 35 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 4e6e6b9..a354498 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -805,11 +805,6 @@ bool QCoreApplication::notify(QObject *receiver, QEvent *event)
d->checkReceiverThread(receiver);
#endif
-#ifdef QT3_SUPPORT
- if (event->type() == QEvent::ChildRemoved && !receiver->d_func()->pendingChildInsertedEvents.isEmpty())
- receiver->d_func()->removePendingChildInsertedEvents(static_cast<QChildEvent *>(event)->child());
-#endif // QT3_SUPPORT
-
return receiver->isWidgetType() ? false : d->notify_helper(receiver, event);
}
@@ -1475,7 +1470,7 @@ void QCoreApplication::removePostedEvents(QObject *receiver, int eventType)
--pe.receiver->d_func()->postedEvents;
#ifdef QT3_SUPPORT
if (pe.event->type() == QEvent::ChildInsertedRequest)
- pe.receiver->d_func()->removePendingChildInsertedEvents(0);
+ pe.receiver->d_func()->pendingChildInsertedEvents.clear();
#endif
pe.event->posted = false;
events.append(pe.event);
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 2648e6e..946c8d4 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -195,8 +195,8 @@ void QObjectPrivate::sendPendingChildInsertedEvents()
{
Q_Q(QObject);
for (int i = 0; i < pendingChildInsertedEvents.size(); ++i) {
- QObject *c = pendingChildInsertedEvents.at(i);
- if (!c)
+ QObject *c = pendingChildInsertedEvents.at(i).data();
+ if (!c || c->parent() != q)
continue;
QChildEvent childEvent(QEvent::ChildInserted, c);
QCoreApplication::sendEvent(q, &childEvent);
@@ -204,26 +204,6 @@ void QObjectPrivate::sendPendingChildInsertedEvents()
pendingChildInsertedEvents.clear();
}
-void QObjectPrivate::removePendingChildInsertedEvents(QObject *child)
-{
- if (!child) {
- pendingChildInsertedEvents.clear();
- return;
- }
-
- // the QObject destructor calls QObject::removeChild, which calls
- // QCoreApplication::sendEvent() directly. this can happen while the event
- // loop is in the middle of posting events, and when we get here, we may
- // not have any more posted events for this object.
-
- // if this is a child remove event and the child insert hasn't
- // been dispatched yet, kill that insert
- for (int i = 0; i < pendingChildInsertedEvents.size(); ++i) {
- QObject *&c = pendingChildInsertedEvents[i];
- if (c == child)
- c = 0;
- }
-}
#endif
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 35b4540..82023d4 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -55,6 +55,7 @@
#include "QtCore/qobject.h"
#include "QtCore/qpointer.h"
+#include "QtCore/qsharedpointer.h"
#include "QtCore/qcoreevent.h"
#include "QtCore/qlist.h"
#include "QtCore/qvector.h"
@@ -153,7 +154,6 @@ public:
#ifdef QT3_SUPPORT
void sendPendingChildInsertedEvents();
- void removePendingChildInsertedEvents(QObject *child);
#endif
static inline Sender *setCurrentSender(QObject *receiver,
@@ -186,7 +186,7 @@ public:
mutable quint32 connectedSignals[2];
#ifdef QT3_SUPPORT
- QList<QObject *> pendingChildInsertedEvents;
+ QVector< QWeakPointer<QObject> > pendingChildInsertedEvents;
#else
// preserve binary compatibility with code compiled without Qt 3 support
// keeping the binary layout stable helps the Qt Creator debugger
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 7b62de1..88d81da 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -3655,11 +3655,6 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
d->checkReceiverThread(receiver);
#endif
-#ifdef QT3_SUPPORT
- if (e->type() == QEvent::ChildRemoved && !receiver->d_func()->pendingChildInsertedEvents.isEmpty())
- receiver->d_func()->removePendingChildInsertedEvents(static_cast<QChildEvent *>(e)->child());
-#endif // QT3_SUPPORT
-
// capture the current mouse/keyboard state
if(e->spontaneous()) {
if (e->type() == QEvent::KeyPress