diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-05-26 08:05:14 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-05-28 08:21:24 (GMT) |
commit | 66d68138c6b21d249daad27c904c688b78d21af6 (patch) | |
tree | 47b59359145d7482c26a13cc7b81d6158a56f527 | |
parent | 8d267e8d7a1e3374558ed302cfa415788ca74e02 (diff) | |
download | Qt-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.cpp | 7 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 24 | ||||
-rw-r--r-- | src/corelib/kernel/qobject_p.h | 4 | ||||
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 5 |
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 |