diff options
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qabstracteventdispatcher.cpp | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 46 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobject.cpp | 10 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 16 |
4 files changed, 50 insertions, 24 deletions
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index 31369f9a09..907b3ccf1f 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -458,7 +458,7 @@ bool QAbstractEventDispatcher::filterNativeEvent(const QByteArray &eventType, vo if (!d->eventFilters.isEmpty()) { // Raise the loopLevel so that deleteLater() calls in or triggered // by event_filter() will be processed from the main event loop. - QScopedLoopLevelCounter loopLevelCounter(d->threadData); + QScopedScopeLevelCounter scopeLevelCounter(d->threadData); for (int i = 0; i < d->eventFilters.size(); ++i) { QAbstractNativeEventFilter *filter = d->eventFilters.at(i); if (!filter) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 60f3dc0db0..42bda25be5 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -980,7 +980,7 @@ bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event) // call overhead. QObjectPrivate *d = receiver->d_func(); QThreadData *threadData = d->threadData; - QScopedLoopLevelCounter loopLevelCounter(threadData); + QScopedScopeLevelCounter scopeLevelCounter(threadData); if (!selfRequired) return doNotify(receiver, event); return self->notify(receiver, event); @@ -1193,6 +1193,9 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags) */ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime) { + // ### Qt 6: consider splitting this method into a public and a private + // one, so that a user-invoked processEvents can be detected + // and handled properly. QThreadData *data = QThreadData::current(); if (!data->hasEventDispatcher()) return; @@ -1396,8 +1399,24 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) if (event->type() == QEvent::DeferredDelete && data == QThreadData::current()) { // remember the current running eventloop for DeferredDelete - // events posted in the receiver's thread - static_cast<QDeferredDeleteEvent *>(event)->level = data->loopLevel; + // events posted in the receiver's thread. + + // Events sent by non-Qt event handlers (such as glib) may not + // have the scopeLevel set correctly. The scope level makes sure that + // code like this: + // foo->deleteLater(); + // qApp->processEvents(); // without passing QEvent::DeferredDelete + // will not cause "foo" to be deleted before returning to the event loop. + + // If the scope level is 0 while loopLevel != 0, we are called from a + // non-conformant code path, and our best guess is that the scope level + // should be 1. (Loop level 0 is special: it means that no event loops + // are running.) + int loopLevel = data->loopLevel; + int scopeLevel = data->scopeLevel; + if (scopeLevel == 0 && loopLevel != 0) + scopeLevel = 1; + static_cast<QDeferredDeleteEvent *>(event)->level = loopLevel + scopeLevel; } // delete the event on exceptions to protect against memory leaks till the event is @@ -1474,6 +1493,9 @@ bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEven */ void QCoreApplication::sendPostedEvents(QObject *receiver, int event_type) { + // ### Qt 6: consider splitting this method into a public and a private + // one, so that a user-invoked sendPostedEvents can be detected + // and handled properly. QThreadData *data = QThreadData::current(); QCoreApplicationPrivate::sendPostedEvents(receiver, event_type, data); @@ -1565,15 +1587,19 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type } if (pe.event->type() == QEvent::DeferredDelete) { - // DeferredDelete events are only sent when we are explicitly asked to - // (s.a. QEvent::DeferredDelete), and then only if the event loop that - // posted the event has returned. - int loopLevel = static_cast<QDeferredDeleteEvent *>(pe.event)->loopLevel(); + // DeferredDelete events are sent either + // 1) when the event loop that posted the event has returned; or + // 2) if explicitly requested (with QEvent::DeferredDelete) for + // events posted by the current event loop; or + // 3) if the event was posted before the outermost event loop. + + int eventLevel = static_cast<QDeferredDeleteEvent *>(pe.event)->loopLevel(); + int loopLevel = data->loopLevel + data->scopeLevel; const bool allowDeferredDelete = - (loopLevel > data->loopLevel - || (!loopLevel && data->loopLevel > 0) + (eventLevel > loopLevel + || (!eventLevel && loopLevel > 0) || (event_type == QEvent::DeferredDelete - && loopLevel == data->loopLevel)); + && eventLevel == loopLevel)); if (!allowDeferredDelete) { // cannot send deferred delete if (!event_type && !receiver) { diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index c5a6875a77..1c426225a5 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -333,14 +333,8 @@ const char *QMetaObject::className() const */ QObject *QMetaObject::cast(QObject *obj) const { - if (obj) { - const QMetaObject *m = obj->metaObject(); - do { - if (m == this) - return obj; - } while ((m = m->d.superdata)); - } - return 0; + // ### Qt 6: inline + return const_cast<QObject*>(cast(const_cast<const QObject*>(obj))); } /*! diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index dea8c200ef..e3e536d7e1 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3713,8 +3713,6 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i if (receiverInSameThread) { sw.switchSender(receiver, sender, signal_index); } - const QObjectPrivate::StaticMetaCallFunction callFunction = c->callFunction; - const int method_relative = c->method_relative; if (c->isSlotObject) { c->slotObj->ref(); QScopedPointer<QtPrivate::QSlotObjectBase, QSlotObjectBaseDeleter> obj(c->slotObj); @@ -3727,10 +3725,12 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i obj.reset(); locker.relock(); - } else if (callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) { + } else if (c->callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) { //we compare the vtable to make sure we are not in the destructor of the object. - locker.unlock(); const int methodIndex = c->method(); + const int method_relative = c->method_relative; + const auto callFunction = c->callFunction; + locker.unlock(); if (qt_signal_spy_callback_set.slot_begin_callback != 0) qt_signal_spy_callback_set.slot_begin_callback(receiver, methodIndex, argv ? argv : empty_argv); @@ -3740,7 +3740,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i qt_signal_spy_callback_set.slot_end_callback(receiver, methodIndex); locker.relock(); } else { - const int method = method_relative + c->method_offset; + const int method = c->method_relative + c->method_offset; locker.unlock(); if (qt_signal_spy_callback_set.slot_begin_callback != 0) { @@ -4538,6 +4538,8 @@ void qDeleteInEventHandler(QObject *o) make sure to declare the argument type with Q_DECLARE_METATYPE + Overloaded functions can be resolved with help of \l qOverload. + \note The number of arguments in the signal or slot are limited to 6 if the compiler does not support C++11 variadic templates. */ @@ -4573,6 +4575,8 @@ void qDeleteInEventHandler(QObject *o) However, you should take care that any objects used within the functor are still alive when the signal is emitted. + Overloaded functions can be resolved with help of \l qOverload. + \note If the compiler does not support C++11 variadic templates, the number of arguments in the signal or slot are limited to 6, and the functor object must not have an overloaded or templated operator(). @@ -4612,6 +4616,8 @@ void qDeleteInEventHandler(QObject *o) However, you should take care that any objects used within the functor are still alive when the signal is emitted. + Overloaded functions can be resolved with help of \l qOverload. + \note If the compiler does not support C++11 variadic templates, the number of arguments in the signal or slot are limited to 6, and the functor object must not have an overloaded or templated operator(). |