summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorSona Kurazyan <sona.kurazyan@qt.io>2020-05-19 14:35:39 +0200
committerSona Kurazyan <sona.kurazyan@qt.io>2020-05-27 11:53:28 +0200
commitd7d6a1fe320eef63c3aac3f18a4cf41221e7b6ad (patch)
treeef37bd6c38602a9e4637c99858192471a09a0c0d /src/corelib/thread
parentd8a2456fbf18f60e2d1950585d93aa530df077bf (diff)
Don't queue events in QFutureWatcher when pause is requested
When QFutureWatcher (or QFutureInterface) is paused, it doesn't mean that it will take effect immediately: the pending tasks may still be in progress and keep reporting results. At the moment QFutureWatcher will queue those events and report only with the next resume. This behavior is wrong, QFutureWatcher should not decide when to report events, the sender should decide when is the right time. There's no benefit in reporting already happened events with delay. Because of this, even the pause event itself was being reported after resume. Fixed the behavior by removing the logic of queueing events when the state is set to "paused". It seems unlikely that the users of QFutureWatcher rely on reporting events with delay. [ChangeLog][Important Behavior Changes][QtCore] QFutureWatcher will not immediately stop delivering progress and result ready signals when the future is paused. At the moment of pausing there may be still computations that are in progress and cannot be stopped. Signals for such computations will be still delivered after pause, instead of being postponed and reported only after next resume. Fixes: QTBUG-12152 Change-Id: I9f0b545ac096578c52cc72d60575c018c01e3368 Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qfuturewatcher.cpp40
-rw-r--r--src/corelib/thread/qfuturewatcher_p.h1
2 files changed, 15 insertions, 26 deletions
diff --git a/src/corelib/thread/qfuturewatcher.cpp b/src/corelib/thread/qfuturewatcher.cpp
index 06bc4740f9..1ab3efee64 100644
--- a/src/corelib/thread/qfuturewatcher.cpp
+++ b/src/corelib/thread/qfuturewatcher.cpp
@@ -137,9 +137,11 @@ void QFutureWatcherBase::cancel()
If \a paused is true, this function pauses the asynchronous computation
represented by the future(). If the computation is already paused, this
- function does nothing. This QFutureWatcher will stop delivering progress
- and result ready signals while the future is paused. Signal delivery will
- continue once the computation is resumed.
+ function does nothing. QFutureWatcher will not immediately stop delivering
+ progress and result ready signals when the future is paused. At the moment
+ of pausing there may still be computations that are in progress and cannot
+ be stopped. Signals for such computations will still be delivered after
+ pause.
If \a paused is false, this function resumes the asynchronous computation.
If the computation was not previously paused, this function does nothing.
@@ -314,25 +316,7 @@ bool QFutureWatcherBase::event(QEvent *event)
Q_D(QFutureWatcherBase);
if (event->type() == QEvent::FutureCallOut) {
QFutureCallOutEvent *callOutEvent = static_cast<QFutureCallOutEvent *>(event);
-
- if (futureInterface().isPaused()) {
- d->pendingCallOutEvents.append(callOutEvent->clone());
- return true;
- }
-
- if (callOutEvent->callOutType == QFutureCallOutEvent::Resumed
- && !d->pendingCallOutEvents.isEmpty()) {
- // send the resume
- d->sendCallOutEvent(callOutEvent);
-
- // next send all pending call outs
- for (int i = 0; i < d->pendingCallOutEvents.count(); ++i)
- d->sendCallOutEvent(d->pendingCallOutEvents.at(i));
- qDeleteAll(d->pendingCallOutEvents);
- d->pendingCallOutEvents.clear();
- } else {
- d->sendCallOutEvent(callOutEvent);
- }
+ d->sendCallOutEvent(callOutEvent);
return true;
}
return QObject::event(event);
@@ -403,8 +387,6 @@ void QFutureWatcherBase::disconnectOutputInterface(bool pendingAssignment)
if (pendingAssignment) {
Q_D(QFutureWatcherBase);
d->pendingResultsReady.storeRelaxed(0);
- qDeleteAll(d->pendingCallOutEvents);
- d->pendingCallOutEvents.clear();
d->finished = false; /* May soon be amended, during connectOutputInterface() */
}
@@ -541,7 +523,15 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event)
*/
/*! \fn template <typename T> void QFutureWatcher<T>::paused()
- This signal is emitted when the watched future is paused.
+ This signal is emitted when the state of the watched future is
+ set to paused.
+
+ \note This signal only informs that pause has been requested. It
+ doesn't indicate that all background operations are stopped. Signals
+ for computations that were in progress at the moment of pausing will
+ still be delivered.
+
+ \sa setPaused(), pause()
*/
/*! \fn template <typename T> void QFutureWatcher<T>::resumed()
diff --git a/src/corelib/thread/qfuturewatcher_p.h b/src/corelib/thread/qfuturewatcher_p.h
index ead247b040..b086b88773 100644
--- a/src/corelib/thread/qfuturewatcher_p.h
+++ b/src/corelib/thread/qfuturewatcher_p.h
@@ -74,7 +74,6 @@ public:
void sendCallOutEvent(QFutureCallOutEvent *event);
- QList<QFutureCallOutEvent *> pendingCallOutEvents;
QAtomicInt pendingResultsReady;
int maximumPendingResultsReady;