From 3af4b59e8b59c7b658c925e1f644d31b89e39896 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 7 Sep 2018 13:48:34 +0200 Subject: glib dispatcher: rework userEventSourcePrepare() event source This is a better solution for fbb485d4f6985643b27da3cc6c5b5f960c32e74d. The existing solution was working fine, but it was exposing logic that is internal to QWindowSystemInterface and platform plugin interaction. Some platform plugins do event filtering at native event level - those that support QAbstractEventDispatcher::filterNativeEvent(). Other plugins rely on QWindowSystemInterface to do the filtering. Dispatchers should not care about this. The new logic rely on the fact that QWindowSystemInterfacePrivate::handleWindowSystemEvent calls QAbstractEventDispatcher::wakeUp(). The same way postEventSourcePrepare() rely on QCoreApplication::postEvent() to call QAbstractEventDispatcher::wakeUp(). Event sources run in the order they are attached, postEventSourcePrepare runs before userEventSourcePrepare(). We rely on that order to pass wakeUpCalled value. Change-Id: I0327f4f2398fd863fb2421b8033bb1df8d65f5af Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Thiago Macieira --- src/corelib/kernel/qeventdispatcher_glib.cpp | 4 ++-- src/corelib/kernel/qeventdispatcher_glib_p.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp index 4c780a9294..45c6e29e4b 100644 --- a/src/corelib/kernel/qeventdispatcher_glib.cpp +++ b/src/corelib/kernel/qeventdispatcher_glib.cpp @@ -260,8 +260,8 @@ static gboolean postEventSourcePrepare(GSource *s, gint *timeout) *timeout = canWait ? -1 : 0; GPostEventSource *source = reinterpret_cast(s); - return (!canWait - || (source->serialNumber.load() != source->lastSerialNumber)); + source->d->wakeUpCalled = source->serialNumber.load() != source->lastSerialNumber; + return !canWait || source->d->wakeUpCalled; } static gboolean postEventSourceCheck(GSource *source) diff --git a/src/corelib/kernel/qeventdispatcher_glib_p.h b/src/corelib/kernel/qeventdispatcher_glib_p.h index 799f23b14a..88ff316ee5 100644 --- a/src/corelib/kernel/qeventdispatcher_glib_p.h +++ b/src/corelib/kernel/qeventdispatcher_glib_p.h @@ -108,6 +108,7 @@ public: GSocketNotifierSource *socketNotifierSource; GTimerSource *timerSource; GIdleTimerSource *idleTimerSource; + bool wakeUpCalled = true; void runTimersOnceWithNormalPriority(); }; -- cgit v1.2.3 From 1f6bfc220774e9407fe88916843b76ed103cff72 Mon Sep 17 00:00:00 2001 From: Cristian Maureira-Fredes Date: Mon, 3 Sep 2018 14:02:13 +0200 Subject: Doc: Move literal code block to a separate file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to override this snippet for the documentation we generate for Qt for Python, and it is easier to have it on a separate file. Task-number: PYSIDE-801 Task-number: PYSIDE-691 Change-Id: Ideb5b6af25024279f167137d3b65660bb9c96a7e Reviewed-by: Topi Reiniö --- src/corelib/kernel/qdeadlinetimer.cpp | 85 ++++++-------------------------- src/corelib/kernel/qmetaobject.cpp | 20 +------- src/corelib/kernel/qobject.cpp | 13 +---- src/corelib/kernel/qtestsupport_core.cpp | 14 +----- 4 files changed, 20 insertions(+), 112 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp index 66d0dce7e8..466056d513 100644 --- a/src/corelib/kernel/qdeadlinetimer.cpp +++ b/src/corelib/kernel/qdeadlinetimer.cpp @@ -75,17 +75,7 @@ Q_DECL_CONST_FUNCTION static inline QPair toSecsAndNSecs(qint64 QDeadlineTimer objects can be passed to functions being called to execute this operation so they know how long to still operate. - \code - void executeOperation(int msecs) - { - QDeadlineTimer deadline(msecs); - do { - if (readFromDevice(deadline.remainingTime()) - break; - waitForReadyRead(deadline); - } while (!deadline.hasExpired()); - } - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 0 Many QDeadlineTimer functions deal with time out values, which all are measured in milliseconds. There are two special values, the same as many @@ -125,15 +115,7 @@ Q_DECL_CONST_FUNCTION static inline QPair toSecsAndNSecs(qint64 \c{std::chrono::time_point} objects. In addition, it is fully compatible with the time literals from C++14, which allow one to write code as: - \code - using namespace std::chrono; - using namespace std::chrono_literals; - - QDeadlineTimer deadline(30s); - device->waitForReadyRead(deadline); - if (deadline.remainingTime() > 300ms) - cleanup(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 1 As can be seen in the example above, QDeadlineTimer offers a templated version of remainingTime() and deadline() that can be used to return @@ -145,13 +127,7 @@ Q_DECL_CONST_FUNCTION static inline QPair toSecsAndNSecs(qint64 Also note that, due to this conversion, the deadlines will not be precise, so the following code is not expected to compare equally: - \code - using namespace std::chrono; - using namespace std::chrono_literals; - auto now = steady_clock::now(); - QDeadlineTimer deadline(now + 1s); - Q_ASSERT(deadline == now + 1s); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 2 \sa QTime, QTimer, QDeadlineTimer, Qt::TimerType */ @@ -246,10 +222,7 @@ QDeadlineTimer::QDeadlineTimer(qint64 msecs, Qt::TimerType type) Q_DECL_NOTHROW This constructor can be used with C++14's user-defined literals for time, such as in: - \code - using namespace std::chrono_literals; - QDeadlineTimer deadline(250ms); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 3 For optimization purposes, if \a remaining is zero or negative, this function may skip obtaining the current time and may instead use a value @@ -339,10 +312,7 @@ void QDeadlineTimer::setPreciseRemainingTime(qint64 secs, qint64 nsecs, Qt::Time This function can be used with C++14's user-defined literals for time, such as in: - \code - using namespace std::chrono_literals; - deadline.setRemainingTime(250ms); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 4 \note Qt detects the necessary C++14 compiler support by way of the feature test recommendations from @@ -415,9 +385,7 @@ void QDeadlineTimer::setTimerType(Qt::TimerType timerType) lock functions in \l QMutex, \l QWaitCondition, \l QSemaphore, or \l QReadWriteLock. For example: - \code - mutex.tryLock(deadline.remainingTime()); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 5 \sa remainingTimeNSecs(), isForever(), hasExpired() */ @@ -469,16 +437,7 @@ qint64 QDeadlineTimer::rawRemainingTimeNSecs() const Q_DECL_NOTHROW overdue, by subtracting QDeadlineTimer::current() or QElapsedTimer::msecsSinceReference(), as in the following example: - \code - qint64 realTimeLeft = deadline.deadline(); - if (realTimeLeft != (std::numeric_limits::max)()) { - realTimeLeft -= QDeadlineTimer::current().deadline(); - // or: - //QElapsedTimer timer; - //timer.start(); - //realTimeLeft -= timer.msecsSinceReference(); - } - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 6 \note Timers that were created as expired have an indetermine time point in the past as their deadline, so the above calculation may not work. @@ -505,11 +464,7 @@ qint64 QDeadlineTimer::deadline() const Q_DECL_NOTHROW overdue, by subtracting QDeadlineTimer::current(), as in the following example: - \code - qint64 realTimeLeft = deadline.deadlineNSecs(); - if (realTimeLeft != std::numeric_limits::max()) - realTimeLeft -= QDeadlineTimer::current().deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 7 \note Timers that were created as expired have an indetermine time point in the past as their deadline, so the above calculation may not work. @@ -614,9 +569,7 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ same, false otherwise. The timer type used to create the two deadlines is ignored. This function is equivalent to: - \code - return d1.deadlineNSecs() == d2.deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 8 \note comparing QDeadlineTimer objects with different timer types is not supported and may result in unpredictable behavior. @@ -630,9 +583,7 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ diferent, false otherwise. The timer type used to create the two deadlines is ignored. This function is equivalent to: - \code - return d1.deadlineNSecs() != d2.deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 9 \note comparing QDeadlineTimer objects with different timer types is not supported and may result in unpredictable behavior. @@ -646,9 +597,7 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ d2, false otherwise. The timer type used to create the two deadlines is ignored. This function is equivalent to: - \code - return d1.deadlineNSecs() < d2.deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 10 \note comparing QDeadlineTimer objects with different timer types is not supported and may result in unpredictable behavior. @@ -662,9 +611,7 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ deadline in \a d2, false otherwise. The timer type used to create the two deadlines is ignored. This function is equivalent to: - \code - return d1.deadlineNSecs() <= d2.deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 11 \note comparing QDeadlineTimer objects with different timer types is not supported and may result in unpredictable behavior. @@ -678,9 +625,7 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ d2, false otherwise. The timer type used to create the two deadlines is ignored. This function is equivalent to: - \code - return d1.deadlineNSecs() > d2.deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 12 \note comparing QDeadlineTimer objects with different timer types is not supported and may result in unpredictable behavior. @@ -694,9 +639,7 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ deadline in \a d2, false otherwise. The timer type used to create the two deadlines is ignored. This function is equivalent to: - \code - return d1.deadlineNSecs() >= d2.deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 13 \note comparing QDeadlineTimer objects with different timer types is not supported and may result in unpredictable behavior. diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index a6ee12ede1..ac911e287b 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1996,27 +1996,11 @@ const char *QMetaMethod::typeName() const Tag information can be added in the following way in the function declaration: - \code - // In the class MainWindow declaration - #ifndef Q_MOC_RUN - // define the tag text as empty, so the compiler doesn't see it - # define MY_CUSTOM_TAG - #endif - ... - private slots: - MY_CUSTOM_TAG void testFunc(); - \endcode + \snippet code/src_corelib_kernel_qmetaobject.cpp 10 and the information can be accessed by using: - \code - MainWindow win; - win.show(); - - int functionIndex = win.metaObject()->indexOfSlot("testFunc()"); - QMetaMethod mm = win.metaObject()->method(functionIndex); - qDebug() << mm.tag(); // prints MY_CUSTOM_TAG - \endcode + \snippet code/src_corelib_kernel_qmetaobject.cpp 11 For the moment, \c moc will extract and record all tags, but it will not handle any of them specially. You can use the tags to annotate your methods diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 3cb8c45b41..07208b7f40 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -526,18 +526,9 @@ void QMetaCallEvent::placeMetaCall(QObject *object) constructor and in the destructor it resets the state to what it was before the constructor ran. - \code - { - const QSignalBlocker blocker(someQObject); - // no signals here - } - \endcode + \snippet code/src_corelib_kernel_qobject.cpp 53 is thus equivalent to - \code - const bool wasBlocked = someQObject->blockSignals(true); - // no signals here - someQObject->blockSignals(wasBlocked); - \endcode + \snippet code/src_corelib_kernel_qobject.cpp 54 except the code using QSignalBlocker is safe in the face of exceptions. diff --git a/src/corelib/kernel/qtestsupport_core.cpp b/src/corelib/kernel/qtestsupport_core.cpp index 240e5795db..d69551a227 100644 --- a/src/corelib/kernel/qtestsupport_core.cpp +++ b/src/corelib/kernel/qtestsupport_core.cpp @@ -68,13 +68,7 @@ Q_CORE_EXPORT void QTestPrivate::qSleep(int ms) Example: - \code - MyObject obj; - obj.startup(); - QTest::qWaitFor([&]() { - return obj.isReady(); - }, 3000); - \endcode + \snippet code/src_corelib_kernel_qtestsupport_core.cpp 0 The code above will wait for the object to become ready, for a maximum of three seconds. @@ -91,11 +85,7 @@ Q_CORE_EXPORT void QTestPrivate::qSleep(int ms) Example: - \code - int i = 0; - while (myNetworkServerNotResponding() && i++ < 50) - QTest::qWait(250); - \endcode + \snippet code/src_corelib_kernel_qtestsupport_core.cpp 1 The code above will wait until the network server is responding for a maximum of about 12.5 seconds. -- cgit v1.2.3 From 25b8af074763c0f9a8fa8fba6ff6ac7235afad87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 7 Sep 2018 10:50:07 +0200 Subject: Clarify behavior of QAbstractEventDispatcher::processEvents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function, although implemented differently in each event dispatcher, is not supposed to process newly posted events, only the events that were queued at the time of the call. This is tested by tst_QEventDispatcher::processEventsOnlySendsQueuedEvents, which is not blacklisted on any platforms, so we know it's the behavior in practice. Change-Id: If9a874eeeb8ebcebe88ed119b065ae12fc545129 Reviewed-by: Paul Wicking Reviewed-by: Edward Welbourne Reviewed-by: Tor Arne Vestbø --- src/corelib/kernel/qabstracteventdispatcher.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index 655fe58f98..8e1b560874 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -207,6 +207,15 @@ QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread) \sa hasPendingEvents() */ +/*! + \internal + + \note processEvents() only processes events queued before the function + is called. Events that are posted while the function runs will be queued + until a later round of event processing. This only applies to posted Qt + events. For timers and system level events, the situation is unknown. +*/ + /*! \fn bool QAbstractEventDispatcher::hasPendingEvents() \deprecated -- cgit v1.2.3 From 7bf4ebfb26e571a582fd4a19edec9aef1aef46cb Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 16 Oct 2018 20:19:35 +0300 Subject: Create empty list only if it's needed in QMetaMethod::parameterNames Change-Id: I2d370dff0c4939f27709db0ebf2b15a15eb14877 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qmetaobject.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index ac911e287b..b647f69978 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1968,9 +1968,8 @@ QList QMetaMethod::parameterTypes() const */ QList QMetaMethod::parameterNames() const { - QList list; if (!mobj) - return list; + return QList(); return QMetaMethodPrivate::get(this)->parameterNames(); } -- cgit v1.2.3 From aa633ff276e593af227d7c4a84db230382185490 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Mon, 15 Oct 2018 20:08:47 +0300 Subject: QMetaEnum: fix UB Check ptr before usage. Change-Id: Iac757a2e260b237d837318932cc0b5896c6e04c2 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/kernel/qmetaobject.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index b647f69978..c642cd07f2 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -2652,8 +2652,10 @@ int QMetaEnum::value(int index) const */ bool QMetaEnum::isFlag() const { + if (!mobj) + return false; const int offset = priv(mobj->d.data)->revision >= 8 ? 2 : 1; - return mobj && mobj->d.data[handle + offset] & EnumIsFlag; + return mobj->d.data[handle + offset] & EnumIsFlag; } /*! @@ -2664,8 +2666,10 @@ bool QMetaEnum::isFlag() const */ bool QMetaEnum::isScoped() const { + if (!mobj) + return false; const int offset = priv(mobj->d.data)->revision >= 8 ? 2 : 1; - return mobj && mobj->d.data[handle + offset] & EnumIsScoped; + return mobj->d.data[handle + offset] & EnumIsScoped; } /*! -- cgit v1.2.3 From 948f8ce2ecb2d6d2713279311d6090268321f0fb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Aug 2018 17:51:51 -0700 Subject: QWinEventNotifier: fix crash on application shutdown The event dispatcher can be null already but we may have outstanding QWinEventNotifier objects (like in a QProcess). Patch-By: Tamas Karpati Task-number: QTBUG-70214 Change-Id: I5e432e273def425ea334fffd154f34abfd6cb11a Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qwineventnotifier.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp index 24de491326..fe086acb5d 100644 --- a/src/corelib/kernel/qwineventnotifier.cpp +++ b/src/corelib/kernel/qwineventnotifier.cpp @@ -256,6 +256,14 @@ static void CALLBACK wfsoCallback(void *context, BOOLEAN /*ignore*/) { QWinEventNotifierPrivate *nd = reinterpret_cast(context); QAbstractEventDispatcher *eventDispatcher = nd->threadData->eventDispatcher.load(); + + // Happens when Q(Core)Application is destroyed before QWinEventNotifier. + // https://bugreports.qt.io/browse/QTBUG-70214 + if (!eventDispatcher) { // perhaps application is shutting down + qWarning("QWinEventNotifier: no event dispatcher, application shutting down? Cannot deliver event."); + return; + } + QEventDispatcherWin32Private *edp = QEventDispatcherWin32Private::get( static_cast(eventDispatcher)); ++nd->signaledCount; -- cgit v1.2.3