Deprecate the pause-related APIs of QFuture* classes
Deprecated the pause-related APIs of QFuture* classes and added alternatives having "suspend" in the name instead. With 2f15927f01ceef0aca490746302a5ea57ea9441c new isSuspended()/suspended() APIs have been added to QFuture* classes for checking if pause/suspension is still in progress or it already took effect. To keep the naming more consistent, renamed: - setPaused() -> setSuspended() - pause() -> suspend() - togglePaused() -> toggleSuspended() - QFutureWatcher::paused() -> QFutureWatcher::suspending() Note that QFuture*::isPaused() now corresponds to (isSuspending() || isSuspended()). [ChangeLog][Deprecation Notice] Deprecated pause-related APIs of QFuture and QFutureWatcher. Added alternatives having "suspend" in the name instead. Change-Id: Ibeb75017a118401d64d18b72fb95d78e28c4661c Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
parent
036c3c19e7
commit
37cfc3c6d2
@ -219,9 +219,9 @@ void ThreadEngineBase::acquireBarrierSemaphore()
|
||||
barrier.acquire();
|
||||
}
|
||||
|
||||
void ThreadEngineBase::reportIfPausedDone() const
|
||||
void ThreadEngineBase::reportIfSuspensionDone() const
|
||||
{
|
||||
if (futureInterface && futureInterface->isPaused())
|
||||
if (futureInterface && futureInterface->isSuspending())
|
||||
futureInterface->reportSuspended();
|
||||
}
|
||||
|
||||
@ -313,11 +313,11 @@ void ThreadEngineBase::run() // implements QRunnable.
|
||||
if (threadThrottleExit()) {
|
||||
return;
|
||||
} else {
|
||||
// If the last worker thread is throttled and the state is paused,
|
||||
// it means that pause has been requested, and it is already
|
||||
// If the last worker thread is throttled and the state is "suspending",
|
||||
// it means that suspension has been requested, and it is already
|
||||
// in effect (because all previous threads have already exited).
|
||||
// Report the "Suspended" state.
|
||||
reportIfPausedDone();
|
||||
reportIfSuspensionDone();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,14 +99,19 @@ public:
|
||||
void setProgressValue(int progress);
|
||||
void setProgressRange(int minimum, int maximum);
|
||||
void acquireBarrierSemaphore();
|
||||
void reportIfPausedDone() const;
|
||||
void reportIfSuspensionDone() const;
|
||||
|
||||
protected: // The user overrides these:
|
||||
virtual void start() {}
|
||||
virtual void finish() {}
|
||||
virtual ThreadFunctionResult threadFunction() { return ThreadFinished; }
|
||||
virtual bool shouldStartThread() { return futureInterface ? !futureInterface->isPaused() : true; }
|
||||
virtual bool shouldThrottleThread() { return futureInterface ? futureInterface->isPaused() : false; }
|
||||
virtual bool shouldStartThread() { return !shouldThrottleThread(); }
|
||||
virtual bool shouldThrottleThread()
|
||||
{
|
||||
return futureInterface ? (futureInterface->isSuspending() || futureInterface->isSuspended())
|
||||
: false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool startThreadInternal();
|
||||
void startThreads();
|
||||
|
@ -109,12 +109,31 @@ public:
|
||||
void cancel() { d.cancel(); }
|
||||
bool isCanceled() const { return d.isCanceled(); }
|
||||
|
||||
void setPaused(bool paused) { d.setPaused(paused); }
|
||||
bool isPaused() const { return d.isPaused(); }
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use setSuspended() instead.")
|
||||
void setPaused(bool paused) { d.setSuspended(paused); }
|
||||
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use isSuspending() or isSuspended() instead.")
|
||||
bool isPaused() const
|
||||
{
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
return d.isPaused();
|
||||
QT_WARNING_POP
|
||||
}
|
||||
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use toggleSuspended() instead.")
|
||||
void togglePaused() { d.toggleSuspended(); }
|
||||
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use suspend() instead.")
|
||||
void pause() { suspend(); }
|
||||
#endif
|
||||
bool isSuspending() const { return d.isSuspending(); }
|
||||
bool isSuspended() const { return d.isSuspended(); }
|
||||
void pause() { setPaused(true); }
|
||||
void resume() { setPaused(false); }
|
||||
void togglePaused() { d.togglePaused(); }
|
||||
void setSuspended(bool suspend) { d.setSuspended(suspend); }
|
||||
void suspend() { setSuspended(true); }
|
||||
void resume() { setSuspended(false); }
|
||||
void toggleSuspended() { d.toggleSuspended(); }
|
||||
|
||||
bool isStarted() const { return d.isStarted(); }
|
||||
bool isFinished() const { return d.isFinished(); }
|
||||
|
@ -104,11 +104,11 @@
|
||||
|
||||
QFuture also offers ways to interact with a runnning computation. For
|
||||
instance, the computation can be canceled with the cancel() function. To
|
||||
pause the computation, use the setPaused() function or one of the pause(),
|
||||
resume(), or togglePaused() convenience functions. Be aware that not all
|
||||
running asynchronous computations can be canceled or paused. For example,
|
||||
the future returned by QtConcurrent::run() cannot be canceled; but the
|
||||
future returned by QtConcurrent::mappedReduced() can.
|
||||
suspend or resume the computation, use the setSuspended() function or one of
|
||||
the suspend(), resume(), or toggleSuspended() convenience functions. Be aware
|
||||
that not all running asynchronous computations can be canceled or suspended.
|
||||
For example, the future returned by QtConcurrent::run() cannot be canceled;
|
||||
but the future returned by QtConcurrent::mappedReduced() can.
|
||||
|
||||
Progress information is provided by the progressValue(),
|
||||
progressMinimum(), progressMaximum(), and progressText() functions. The
|
||||
@ -116,7 +116,7 @@
|
||||
the computation to finish, ensuring that all results are available.
|
||||
|
||||
The state of the computation represented by a QFuture can be queried using
|
||||
the isCanceled(), isStarted(), isFinished(), isRunning(), isPaused()
|
||||
the isCanceled(), isStarted(), isFinished(), isRunning(), isSuspending()
|
||||
or isSuspended() functions.
|
||||
|
||||
QFuture is a lightweight reference counted class that can be passed by
|
||||
@ -204,8 +204,13 @@
|
||||
function returns \c true. See cancel() for more details.
|
||||
*/
|
||||
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
/*! \fn template <typename T> void QFuture<T>::setPaused(bool paused)
|
||||
|
||||
\obsolete
|
||||
Use setSuspended() instead.
|
||||
|
||||
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. Any QFutureWatcher object that is watching this
|
||||
@ -225,6 +230,9 @@
|
||||
|
||||
/*! \fn template <typename T> bool QFuture<T>::isPaused() const
|
||||
|
||||
\obsolete
|
||||
Use isSuspending() or isSuspended() instead.
|
||||
|
||||
Returns \c true if the asynchronous computation has been paused with the
|
||||
pause() function; otherwise returns \c false.
|
||||
|
||||
@ -235,32 +243,22 @@
|
||||
\sa setPaused(), togglePaused(), isSuspended()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> bool QFuture<T>::isSuspended() const
|
||||
|
||||
Returns \c true if a paused asynchronous computation has been suspended,
|
||||
and no more results or progress changes are expected.
|
||||
|
||||
\sa setPaused(), togglePaused(), isPaused()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> void QFuture<T>::pause()
|
||||
|
||||
\obsolete
|
||||
Use suspend() instead.
|
||||
|
||||
Pauses the asynchronous computation represented by this future. This is a
|
||||
convenience method that simply calls setPaused(true).
|
||||
|
||||
\sa resume()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> void QFuture<T>::resume()
|
||||
|
||||
Resumes the asynchronous computation represented by this future. This is a
|
||||
convenience method that simply calls setPaused(false).
|
||||
|
||||
\sa pause()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> void QFuture<T>::togglePaused()
|
||||
|
||||
\obsolete
|
||||
Use toggleSuspended() instead.
|
||||
|
||||
Toggles the paused state of the asynchronous computation. In other words,
|
||||
if the computation is currently paused, calling this function resumes it;
|
||||
if the computation is running, it is paused. This is a convenience method
|
||||
@ -268,6 +266,82 @@
|
||||
|
||||
\sa setPaused(), pause(), resume()
|
||||
*/
|
||||
#endif // QT_DEPRECATED_SINCE(6, 0)
|
||||
|
||||
/*! \fn template <typename T> void QFuture<T>::setSuspended(bool suspend)
|
||||
|
||||
\since 6.0
|
||||
|
||||
If \a suspend is true, this function suspends the asynchronous computation
|
||||
represented by the future(). If the computation is already suspended, this
|
||||
function does nothing. QFutureWatcher will not immediately stop delivering
|
||||
progress and result ready signals when the future is suspended. At the moment
|
||||
of suspending there may still be computations that are in progress and cannot
|
||||
be stopped. Signals for such computations will still be delivered.
|
||||
|
||||
If \a suspend is false, this function resumes the asynchronous computation.
|
||||
If the computation was not previously suspended, this function does nothing.
|
||||
|
||||
Be aware that not all computations can be suspended. For example, the
|
||||
QFuture returned by QtConcurrent::run() cannot be suspended; but the QFuture
|
||||
returned by QtConcurrent::mappedReduced() can.
|
||||
|
||||
\sa suspend(), resume(), toggleSuspended()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> bool QFuture<T>::isSuspending() const
|
||||
|
||||
\since 6.0
|
||||
|
||||
Returns \c true if the asynchronous computation has been suspended with the
|
||||
suspend() function, but the work is not yet suspended, and computation is still
|
||||
running. Returns \c false otherwise.
|
||||
|
||||
To check if suspension is actually in effect, use isSuspended() instead.
|
||||
|
||||
\sa setSuspended(), toggleSuspended(), isSuspended()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> bool QFuture<T>::isSuspended() const
|
||||
|
||||
\since 6.0
|
||||
|
||||
Returns \c true if a suspension of the asynchronous computation has been
|
||||
requested, and it is in effect, meaning that no more results or progress
|
||||
changes are expected.
|
||||
|
||||
\sa setSuspended(), toggleSuspended(), isSuspending()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> void QFuture<T>::suspend()
|
||||
|
||||
\since 6.0
|
||||
|
||||
Suspends the asynchronous computation represented by this future. This is a
|
||||
convenience method that simply calls setSuspended(true).
|
||||
|
||||
\sa resume()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> void QFuture<T>::resume()
|
||||
|
||||
Resumes the asynchronous computation represented by the future(). This is
|
||||
a convenience method that simply calls setSuspended(false).
|
||||
|
||||
\sa suspend()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> void QFuture<T>::toggleSuspended()
|
||||
|
||||
\since 6.0
|
||||
|
||||
Toggles the suspended state of the asynchronous computation. In other words,
|
||||
if the computation is currently suspending or suspended, calling this
|
||||
function resumes it; if the computation is running, it is suspended. This is a
|
||||
convenience method for calling setSuspended(!(isSuspending() || isSuspended())).
|
||||
|
||||
\sa setSuspended(), suspend(), resume()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> bool QFuture<T>::isStarted() const
|
||||
|
||||
|
@ -65,6 +65,10 @@ public:
|
||||
~ThreadPoolThreadReleaser()
|
||||
{ if (m_pool) m_pool->reserveThread(); }
|
||||
};
|
||||
|
||||
const auto suspendingOrSuspended =
|
||||
QFutureInterfaceBase::Suspending | QFutureInterfaceBase::Suspended;
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
@ -110,36 +114,36 @@ void QFutureInterfaceBase::cancel()
|
||||
if (d->state.loadRelaxed() & Canceled)
|
||||
return;
|
||||
|
||||
switch_from_to(d->state, Paused | Suspended, Canceled);
|
||||
switch_from_to(d->state, suspendingOrSuspended, Canceled);
|
||||
d->waitCondition.wakeAll();
|
||||
d->pausedWaitCondition.wakeAll();
|
||||
d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Canceled));
|
||||
d->isValid = false;
|
||||
}
|
||||
|
||||
void QFutureInterfaceBase::setPaused(bool paused)
|
||||
void QFutureInterfaceBase::setSuspended(bool suspend)
|
||||
{
|
||||
QMutexLocker locker(&d->m_mutex);
|
||||
if (paused) {
|
||||
switch_on(d->state, Paused);
|
||||
d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Paused));
|
||||
if (suspend) {
|
||||
switch_on(d->state, Suspending);
|
||||
d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Suspending));
|
||||
} else {
|
||||
switch_off(d->state, Paused | Suspended);
|
||||
switch_off(d->state, suspendingOrSuspended);
|
||||
d->pausedWaitCondition.wakeAll();
|
||||
d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Resumed));
|
||||
}
|
||||
}
|
||||
|
||||
void QFutureInterfaceBase::togglePaused()
|
||||
void QFutureInterfaceBase::toggleSuspended()
|
||||
{
|
||||
QMutexLocker locker(&d->m_mutex);
|
||||
if (d->state.loadRelaxed() & Paused) {
|
||||
switch_off(d->state, Paused | Suspended);
|
||||
if (d->state.loadRelaxed() & suspendingOrSuspended) {
|
||||
switch_off(d->state, suspendingOrSuspended);
|
||||
d->pausedWaitCondition.wakeAll();
|
||||
d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Resumed));
|
||||
} else {
|
||||
switch_on(d->state, Paused);
|
||||
d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Paused));
|
||||
switch_on(d->state, Suspending);
|
||||
d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Suspending));
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,10 +154,10 @@ void QFutureInterfaceBase::reportSuspended() const
|
||||
|
||||
QMutexLocker locker(&d->m_mutex);
|
||||
const int state = d->state;
|
||||
if (!(state & Paused) || (state & Suspended))
|
||||
if (!(state & Suspending) || (state & Suspended))
|
||||
return;
|
||||
|
||||
switch_on(d->state, Suspended);
|
||||
switch_from_to(d->state, Suspending, Suspended);
|
||||
d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Suspended));
|
||||
}
|
||||
|
||||
@ -164,7 +168,7 @@ void QFutureInterfaceBase::setThrottled(bool enable)
|
||||
switch_on(d->state, Throttled);
|
||||
} else {
|
||||
switch_off(d->state, Throttled);
|
||||
if (!(d->state.loadRelaxed() & Paused))
|
||||
if (!(d->state.loadRelaxed() & suspendingOrSuspended))
|
||||
d->pausedWaitCondition.wakeAll();
|
||||
}
|
||||
}
|
||||
@ -190,10 +194,17 @@ bool QFutureInterfaceBase::isFinished() const
|
||||
return queryState(Finished);
|
||||
}
|
||||
|
||||
bool QFutureInterfaceBase::isSuspending() const
|
||||
{
|
||||
return queryState(Suspending);
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
bool QFutureInterfaceBase::isPaused() const
|
||||
{
|
||||
return queryState(Paused);
|
||||
return queryState(static_cast<State>(suspendingOrSuspended));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool QFutureInterfaceBase::isSuspended() const
|
||||
{
|
||||
@ -233,13 +244,13 @@ void QFutureInterfaceBase::waitForResume()
|
||||
// return early if possible to avoid taking the mutex lock.
|
||||
{
|
||||
const int state = d->state.loadRelaxed();
|
||||
if (!(state & Paused) || (state & Canceled))
|
||||
if (!(state & suspendingOrSuspended) || (state & Canceled))
|
||||
return;
|
||||
}
|
||||
|
||||
QMutexLocker lock(&d->m_mutex);
|
||||
const int state = d->state.loadRelaxed();
|
||||
if (!(state & Paused) || (state & Canceled))
|
||||
if (!(state & suspendingOrSuspended) || (state & Canceled))
|
||||
return;
|
||||
|
||||
// decrease active thread count since this thread will wait.
|
||||
@ -576,7 +587,7 @@ void QFutureInterfaceBasePrivate::internal_setThrottled(bool enable)
|
||||
switch_on(state, QFutureInterfaceBase::Throttled);
|
||||
} else {
|
||||
switch_off(state, QFutureInterfaceBase::Throttled);
|
||||
if (!(state.loadRelaxed() & QFutureInterfaceBase::Paused))
|
||||
if (!(state.loadRelaxed() & suspendingOrSuspended))
|
||||
pausedWaitCondition.wakeAll();
|
||||
}
|
||||
}
|
||||
@ -611,7 +622,8 @@ void QFutureInterfaceBasePrivate::connectOutputInterface(QFutureCallOutInterface
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (state.loadRelaxed() & QFutureInterfaceBase::Started) {
|
||||
const auto currentState = state.loadRelaxed();
|
||||
if (currentState & QFutureInterfaceBase::Started) {
|
||||
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Started));
|
||||
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::ProgressRange,
|
||||
m_progressMinimum,
|
||||
@ -631,15 +643,15 @@ void QFutureInterfaceBasePrivate::connectOutputInterface(QFutureCallOutInterface
|
||||
it.batchedAdvance();
|
||||
}
|
||||
|
||||
if (state.loadRelaxed() & QFutureInterfaceBase::Suspended)
|
||||
if (currentState & QFutureInterfaceBase::Suspended)
|
||||
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Suspended));
|
||||
else if (state.loadRelaxed() & QFutureInterfaceBase::Paused)
|
||||
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Paused));
|
||||
else if (currentState & QFutureInterfaceBase::Suspending)
|
||||
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Suspending));
|
||||
|
||||
if (state.loadRelaxed() & QFutureInterfaceBase::Canceled)
|
||||
if (currentState & QFutureInterfaceBase::Canceled)
|
||||
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Canceled));
|
||||
|
||||
if (state.loadRelaxed() & QFutureInterfaceBase::Finished)
|
||||
if (currentState & QFutureInterfaceBase::Finished)
|
||||
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Finished));
|
||||
|
||||
outputConnections.append(interface);
|
||||
|
@ -77,16 +77,16 @@ class Q_CORE_EXPORT QFutureInterfaceBase
|
||||
{
|
||||
public:
|
||||
enum State {
|
||||
NoState = 0x00,
|
||||
Running = 0x01,
|
||||
Started = 0x02,
|
||||
Finished = 0x04,
|
||||
Canceled = 0x08,
|
||||
Paused = 0x10,
|
||||
Throttled = 0x20,
|
||||
NoState = 0x00,
|
||||
Running = 0x01,
|
||||
Started = 0x02,
|
||||
Finished = 0x04,
|
||||
Canceled = 0x08,
|
||||
Suspending = 0x10,
|
||||
Suspended = 0x20,
|
||||
Throttled = 0x40,
|
||||
// Pending means that the future depends on another one, which is not finished yet
|
||||
Pending = 0x40,
|
||||
Suspended = 0x80
|
||||
Pending = 0x80,
|
||||
};
|
||||
|
||||
QFutureInterfaceBase(State initialState = NoState);
|
||||
@ -125,15 +125,25 @@ public:
|
||||
bool isStarted() const;
|
||||
bool isCanceled() const;
|
||||
bool isFinished() const;
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use isSuspending() or isSuspended() instead.")
|
||||
bool isPaused() const;
|
||||
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use setSuspended() instead.")
|
||||
void setPaused(bool paused) { setSuspended(paused); }
|
||||
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use toggleSuspended() instead.")
|
||||
void togglePaused() { toggleSuspended(); }
|
||||
#endif
|
||||
bool isSuspending() const;
|
||||
bool isSuspended() const;
|
||||
bool isThrottled() const;
|
||||
bool isResultReadyAt(int index) const;
|
||||
bool isValid() const;
|
||||
|
||||
void cancel();
|
||||
void setPaused(bool paused);
|
||||
void togglePaused();
|
||||
void setSuspended(bool suspend);
|
||||
void toggleSuspended();
|
||||
void reportSuspended() const;
|
||||
void setThrottled(bool enable);
|
||||
|
||||
|
@ -70,12 +70,12 @@ public:
|
||||
Started,
|
||||
Finished,
|
||||
Canceled,
|
||||
Paused,
|
||||
Suspending,
|
||||
Suspended,
|
||||
Resumed,
|
||||
Progress,
|
||||
ProgressRange,
|
||||
ResultsReady,
|
||||
Suspended
|
||||
ResultsReady
|
||||
};
|
||||
|
||||
QFutureCallOutEvent()
|
||||
|
@ -64,12 +64,12 @@ QT_BEGIN_NAMESPACE
|
||||
For convenience, several of QFuture's functions are also available in
|
||||
QFutureWatcher: progressValue(), progressMinimum(), progressMaximum(),
|
||||
progressText(), isStarted(), isFinished(), isRunning(), isCanceled(),
|
||||
isPaused(), waitForFinished(), result(), and resultAt(). The cancel(),
|
||||
setPaused(), pause(), resume(), and togglePaused() functions are slots in
|
||||
QFutureWatcher.
|
||||
isSuspending(), isSuspended(), waitForFinished(), result(), and resultAt().
|
||||
The cancel(), setSuspended(), suspend(), resume(), and toggleSuspended() functions
|
||||
are slots in QFutureWatcher.
|
||||
|
||||
Status changes are reported via the started(), finished(), canceled(),
|
||||
paused(), resumed(), suspended(), resultReadyAt(), and resultsReadyAt()
|
||||
suspending(), suspended(), resumed(), resultReadyAt(), and resultsReadyAt()
|
||||
signals. Progress information is provided from the progressRangeChanged(),
|
||||
void progressValueChanged(), and progressTextChanged() signals.
|
||||
|
||||
@ -85,7 +85,7 @@ QT_BEGIN_NAMESPACE
|
||||
\snippet code/src_corelib_thread_qfuturewatcher.cpp 0
|
||||
|
||||
Be aware that not all running asynchronous computations can be canceled or
|
||||
paused. For example, the future returned by QtConcurrent::run() cannot be
|
||||
suspended. For example, the future returned by QtConcurrent::run() cannot be
|
||||
canceled; but the future returned by QtConcurrent::mappedReduced() can.
|
||||
|
||||
QFutureWatcher<void> is specialized to not contain any of the result
|
||||
@ -133,8 +133,12 @@ void QFutureWatcherBase::cancel()
|
||||
futureInterface().cancel();
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
/*! \fn template <typename T> void QFutureWatcher<T>::setPaused(bool paused)
|
||||
|
||||
\obsolete
|
||||
Use setSuspended() instead.
|
||||
|
||||
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. QFutureWatcher will not immediately stop delivering
|
||||
@ -154,11 +158,14 @@ void QFutureWatcherBase::cancel()
|
||||
*/
|
||||
void QFutureWatcherBase::setPaused(bool paused)
|
||||
{
|
||||
futureInterface().setPaused(paused);
|
||||
futureInterface().setSuspended(paused);
|
||||
}
|
||||
|
||||
/*! \fn template <typename T> void QFutureWatcher<T>::pause()
|
||||
|
||||
\obsolete
|
||||
Use suspend() instead.
|
||||
|
||||
Pauses the asynchronous computation represented by the future(). This is a
|
||||
convenience method that simply calls setPaused(true).
|
||||
|
||||
@ -166,33 +173,96 @@ void QFutureWatcherBase::setPaused(bool paused)
|
||||
*/
|
||||
void QFutureWatcherBase::pause()
|
||||
{
|
||||
futureInterface().setPaused(true);
|
||||
futureInterface().setSuspended(true);
|
||||
}
|
||||
|
||||
#endif // QT_DEPRECATED_SINCE(6, 0)
|
||||
|
||||
/*! \fn template <typename T> void QFutureWatcher<T>::setSuspended(bool suspend)
|
||||
|
||||
\since 6.0
|
||||
|
||||
If \a suspend is true, this function suspends the asynchronous computation
|
||||
represented by the future(). If the computation is already suspended, this
|
||||
function does nothing. QFutureWatcher will not immediately stop delivering
|
||||
progress and result ready signals when the future is suspended. At the moment
|
||||
of suspending there may still be computations that are in progress and cannot
|
||||
be stopped. Signals for such computations will still be delivered.
|
||||
|
||||
If \a suspend is false, this function resumes the asynchronous computation.
|
||||
If the computation was not previously suspended, this function does nothing.
|
||||
|
||||
Be aware that not all computations can be suspended. For example, the
|
||||
QFuture returned by QtConcurrent::run() cannot be suspended; but the QFuture
|
||||
returned by QtConcurrent::mappedReduced() can.
|
||||
|
||||
\sa suspend(), resume(), toggleSuspended()
|
||||
*/
|
||||
void QFutureWatcherBase::setSuspended(bool suspend)
|
||||
{
|
||||
futureInterface().setSuspended(suspend);
|
||||
}
|
||||
|
||||
/*! \fn template <typename T> void QFutureWatcher<T>::suspend()
|
||||
|
||||
\since 6.0
|
||||
|
||||
Suspends the asynchronous computation represented by this future. This is a
|
||||
convenience method that simply calls setSuspended(true).
|
||||
|
||||
\sa resume()
|
||||
*/
|
||||
void QFutureWatcherBase::suspend()
|
||||
{
|
||||
futureInterface().setSuspended(true);
|
||||
}
|
||||
|
||||
/*! \fn template <typename T> void QFutureWatcher<T>::resume()
|
||||
|
||||
Resumes the asynchronous computation represented by the future(). This is
|
||||
a convenience method that simply calls setPaused(false).
|
||||
a convenience method that simply calls setSuspended(false).
|
||||
|
||||
\sa pause()
|
||||
\sa suspend()
|
||||
*/
|
||||
|
||||
void QFutureWatcherBase::resume()
|
||||
{
|
||||
futureInterface().setPaused(false);
|
||||
futureInterface().setSuspended(false);
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
/*! \fn template <typename T> void QFutureWatcher<T>::togglePaused()
|
||||
|
||||
\obsolete
|
||||
Use toggleSuspended() instead.
|
||||
|
||||
Toggles the paused state of the asynchronous computation. In other words,
|
||||
if the computation is currently paused, calling this function resumes it;
|
||||
if the computation is running, it becomes paused. This is a convenience
|
||||
method for calling setPaused(!isPaused()).
|
||||
if the computation is running, it is paused. This is a convenience method
|
||||
for calling setPaused(!isPaused()).
|
||||
|
||||
\sa setPaused(), pause(), resume()
|
||||
*/
|
||||
void QFutureWatcherBase::togglePaused()
|
||||
{
|
||||
futureInterface().togglePaused();
|
||||
futureInterface().toggleSuspended();
|
||||
}
|
||||
#endif // QT_DEPRECATED_SINCE(6, 0)
|
||||
|
||||
/*! \fn template <typename T> void QFutureWatcher<T>::toggleSuspended()
|
||||
|
||||
\since 6.0
|
||||
|
||||
Toggles the suspended state of the asynchronous computation. In other words,
|
||||
if the computation is currently suspending or suspended, calling this
|
||||
function resumes it; if the computation is running, it is suspended. This is a
|
||||
convenience method for calling setSuspended(!(isSuspending() || isSuspended())).
|
||||
|
||||
\sa setSuspended(), suspend(), resume()
|
||||
*/
|
||||
void QFutureWatcherBase::toggleSuspended()
|
||||
{
|
||||
futureInterface().toggleSuspended();
|
||||
}
|
||||
|
||||
/*! \fn template <typename T> int QFutureWatcher<T>::progressValue() const
|
||||
@ -286,8 +356,13 @@ bool QFutureWatcherBase::isCanceled() const
|
||||
return futureInterface().queryState(QFutureInterfaceBase::Canceled);
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
|
||||
/*! \fn template <typename T> bool QFutureWatcher<T>::isPaused() const
|
||||
|
||||
\obsolete
|
||||
Use isSuspending() or isSuspended() instead.
|
||||
|
||||
Returns \c true if the asynchronous computation has been paused with the
|
||||
pause() function; otherwise returns \c false.
|
||||
|
||||
@ -297,17 +372,42 @@ bool QFutureWatcherBase::isCanceled() const
|
||||
|
||||
\sa setPaused(), togglePaused(), isSuspended()
|
||||
*/
|
||||
|
||||
bool QFutureWatcherBase::isPaused() const
|
||||
{
|
||||
return futureInterface().queryState(QFutureInterfaceBase::Paused);
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
return futureInterface().isPaused();
|
||||
QT_WARNING_POP
|
||||
}
|
||||
#endif // QT_DEPRECATED_SINCE(6, 0)
|
||||
|
||||
/*! \fn template <typename T> bool QFutureWatcher<T>::isSuspending() const
|
||||
|
||||
\since 6.0
|
||||
|
||||
Returns \c true if the asynchronous computation has been suspended with the
|
||||
suspend() function, but the work is not yet suspended, and computation is still
|
||||
running. Returns \c false otherwise.
|
||||
|
||||
To check if suspension is actually in effect, use isSuspended() instead.
|
||||
|
||||
\sa setSuspended(), toggleSuspended(), isSuspended()
|
||||
*/
|
||||
bool QFutureWatcherBase::isSuspending() const
|
||||
{
|
||||
return futureInterface().isSuspending();
|
||||
}
|
||||
|
||||
/*! \fn template <typename T> bool QFutureWatcher<T>::isSuspended() const
|
||||
|
||||
Returns \c true if a paused asynchronous computation has been suspended,
|
||||
and no more results or progress changes are expected.
|
||||
\since 6.0
|
||||
|
||||
\sa suspended(), paused(), isPaused()
|
||||
Returns \c true if a suspension of the asynchronous computation has been
|
||||
requested, and it is in effect, meaning that no more results or progress
|
||||
changes are expected.
|
||||
|
||||
\sa suspended(), setSuspended(), isSuspending()
|
||||
*/
|
||||
bool QFutureWatcherBase::isSuspended() const
|
||||
{
|
||||
@ -439,10 +539,16 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event)
|
||||
pendingResultsReady.storeRelaxed(0);
|
||||
emit q->canceled();
|
||||
break;
|
||||
case QFutureCallOutEvent::Paused:
|
||||
case QFutureCallOutEvent::Suspending:
|
||||
if (q->futureInterface().isCanceled())
|
||||
break;
|
||||
emit q->suspending();
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
emit q->paused();
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
break;
|
||||
case QFutureCallOutEvent::Suspended:
|
||||
if (q->futureInterface().isCanceled())
|
||||
@ -540,7 +646,28 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event)
|
||||
This signal is emitted if the watched future is canceled.
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> void QFutureWatcher<T>::suspending()
|
||||
|
||||
\since 6.0
|
||||
|
||||
This signal is emitted when the state of the watched future is
|
||||
set to suspended.
|
||||
|
||||
\note This signal only informs that suspension has been requested. It
|
||||
doesn't indicate that all background operations are stopped. Signals
|
||||
for computations that were in progress at the moment of suspending will
|
||||
still be delivered. To be informed when suspension actually
|
||||
took effect, use the suspended() signal.
|
||||
|
||||
\sa setSuspended(), suspend(), suspended()
|
||||
*/
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
/*! \fn template <typename T> void QFutureWatcher<T>::paused()
|
||||
|
||||
\obsolete
|
||||
Use suspending() instead.
|
||||
|
||||
This signal is emitted when the state of the watched future is
|
||||
set to paused.
|
||||
|
||||
@ -552,13 +679,17 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event)
|
||||
|
||||
\sa setPaused(), pause(), suspended()
|
||||
*/
|
||||
#endif // QT_DEPRECATED_SINCE(6, 0)
|
||||
|
||||
/*! \fn template <typename T> void QFutureWatcher<T>::suspended()
|
||||
This signal is emitted when pause() took effect, meaning that there are
|
||||
|
||||
\since 6.0
|
||||
|
||||
This signal is emitted when suspend() took effect, meaning that there are
|
||||
no more running computations. After receiving this signal no more result
|
||||
ready or progress reporting signals are expected.
|
||||
|
||||
\sa setPaused(), pause(), paused()
|
||||
\sa setSuspended(), suspend(), suspended()
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> void QFutureWatcher<T>::resumed()
|
||||
|
@ -69,7 +69,11 @@ public:
|
||||
bool isFinished() const;
|
||||
bool isRunning() const;
|
||||
bool isCanceled() const;
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use isSuspending() or isSuspended() instead.")
|
||||
bool isPaused() const;
|
||||
#endif
|
||||
bool isSuspending() const;
|
||||
bool isSuspended() const;
|
||||
|
||||
void waitForFinished();
|
||||
@ -82,7 +86,11 @@ Q_SIGNALS:
|
||||
void started();
|
||||
void finished();
|
||||
void canceled();
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use suspending() instead.")
|
||||
void paused();
|
||||
#endif
|
||||
void suspending();
|
||||
void suspended();
|
||||
void resumed();
|
||||
void resultReadyAt(int resultIndex);
|
||||
@ -93,10 +101,21 @@ Q_SIGNALS:
|
||||
|
||||
public Q_SLOTS:
|
||||
void cancel();
|
||||
void setPaused(bool paused);
|
||||
void pause();
|
||||
void setSuspended(bool suspend);
|
||||
void suspend();
|
||||
void resume();
|
||||
void toggleSuspended();
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use setSuspended() instead.")
|
||||
void setPaused(bool paused);
|
||||
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use suspended() instead.")
|
||||
void pause();
|
||||
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use toggleSuspended() instead.")
|
||||
void togglePaused();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void connectNotify (const QMetaMethod &signal) override;
|
||||
@ -148,8 +167,11 @@ public:
|
||||
bool isFinished() const;
|
||||
bool isRunning() const;
|
||||
bool isCanceled() const;
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
bool isPaused() const;
|
||||
bool isSuspended() const
|
||||
#endif
|
||||
bool isSuspending() const;
|
||||
bool isSuspended() const;
|
||||
|
||||
void waitForFinished();
|
||||
|
||||
@ -159,7 +181,10 @@ Q_SIGNALS:
|
||||
void started();
|
||||
void finished();
|
||||
void canceled();
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
void paused();
|
||||
#endif
|
||||
void suspending();
|
||||
void suspended();
|
||||
void resumed();
|
||||
void resultReadyAt(int resultIndex);
|
||||
@ -170,11 +195,17 @@ Q_SIGNALS:
|
||||
|
||||
public Q_SLOTS:
|
||||
void cancel();
|
||||
void setSuspended(bool suspend);
|
||||
void suspend();
|
||||
void resume();
|
||||
void toggleSuspended();
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
void setPaused(bool paused);
|
||||
void pause();
|
||||
void resume();
|
||||
void togglePaused();
|
||||
#endif
|
||||
#endif // QT_DEPRECATED_SINCE(6, 0)
|
||||
|
||||
#endif // Q_QDOC
|
||||
|
||||
private:
|
||||
QFuture<T> m_future;
|
||||
|
@ -112,7 +112,10 @@ private slots:
|
||||
void implicitConversions();
|
||||
void iterators();
|
||||
void iteratorsThread();
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
void pause();
|
||||
void suspendCheckPaused();
|
||||
#endif
|
||||
void suspend();
|
||||
void throttling();
|
||||
void voidConversions();
|
||||
@ -1315,6 +1318,9 @@ public:
|
||||
QSet<int> reportedProgress;
|
||||
};
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
void tst_QFuture::pause()
|
||||
{
|
||||
QFutureInterface<void> Interface;
|
||||
@ -1335,39 +1341,98 @@ void tst_QFuture::pause()
|
||||
Interface.reportFinished();
|
||||
}
|
||||
|
||||
void tst_QFuture::suspendCheckPaused()
|
||||
{
|
||||
QFutureInterface<void> interface;
|
||||
|
||||
interface.reportStarted();
|
||||
QFuture<void> f = interface.future();
|
||||
QVERIFY(!f.isSuspended());
|
||||
|
||||
interface.reportSuspended();
|
||||
QVERIFY(!f.isSuspended());
|
||||
|
||||
f.pause();
|
||||
QVERIFY(!f.isSuspended());
|
||||
QVERIFY(f.isPaused());
|
||||
|
||||
// resume when still pausing
|
||||
f.resume();
|
||||
QVERIFY(!f.isSuspended());
|
||||
QVERIFY(!f.isPaused());
|
||||
|
||||
// pause again
|
||||
f.pause();
|
||||
QVERIFY(!f.isSuspended());
|
||||
QVERIFY(f.isPaused());
|
||||
|
||||
interface.reportSuspended();
|
||||
QVERIFY(f.isSuspended());
|
||||
QVERIFY(f.isPaused());
|
||||
|
||||
// resume after suspended
|
||||
f.resume();
|
||||
QVERIFY(!f.isSuspended());
|
||||
QVERIFY(!f.isPaused());
|
||||
|
||||
// pause again and cancel
|
||||
f.pause();
|
||||
interface.reportSuspended();
|
||||
|
||||
interface.reportCanceled();
|
||||
QVERIFY(!f.isSuspended());
|
||||
QVERIFY(!f.isPaused());
|
||||
QVERIFY(f.isCanceled());
|
||||
|
||||
interface.reportFinished();
|
||||
}
|
||||
|
||||
QT_WARNING_POP
|
||||
#endif // QT_DEPRECATED_SINCE(6, 0)
|
||||
|
||||
void tst_QFuture::suspend()
|
||||
{
|
||||
QFutureInterface<void> interface;
|
||||
|
||||
interface.reportStarted();
|
||||
QFuture<void> f = interface.future();
|
||||
QVERIFY(!interface.isSuspended());
|
||||
QVERIFY(!f.isSuspended());
|
||||
|
||||
interface.reportSuspended();
|
||||
QVERIFY(!interface.isSuspended());
|
||||
QVERIFY(!f.isSuspended());
|
||||
QVERIFY(!f.isSuspending());
|
||||
|
||||
// pause
|
||||
interface.togglePaused();
|
||||
QVERIFY(!interface.isSuspended());
|
||||
QVERIFY(interface.isPaused());
|
||||
f.suspend();
|
||||
QVERIFY(f.isSuspending());
|
||||
QVERIFY(!f.isSuspended());
|
||||
|
||||
// resume when still suspending
|
||||
f.resume();
|
||||
QVERIFY(!f.isSuspending());
|
||||
QVERIFY(!f.isSuspended());
|
||||
|
||||
// suspend again
|
||||
f.suspend();
|
||||
QVERIFY(f.isSuspending());
|
||||
QVERIFY(!f.isSuspended());
|
||||
|
||||
interface.reportSuspended();
|
||||
QVERIFY(interface.isSuspended());
|
||||
QVERIFY(interface.isPaused());
|
||||
QVERIFY(!f.isSuspending());
|
||||
QVERIFY(f.isSuspended());
|
||||
|
||||
// resume
|
||||
interface.togglePaused();
|
||||
QVERIFY(!interface.isSuspended());
|
||||
QVERIFY(!interface.isPaused());
|
||||
// resume after suspended
|
||||
f.resume();
|
||||
QVERIFY(!f.isSuspending());
|
||||
QVERIFY(!f.isSuspended());
|
||||
|
||||
// pause again
|
||||
interface.togglePaused();
|
||||
// suspend again and cancel
|
||||
f.suspend();
|
||||
interface.reportSuspended();
|
||||
|
||||
interface.reportCanceled();
|
||||
QVERIFY(!interface.isSuspended());
|
||||
QVERIFY(!interface.isPaused());
|
||||
QVERIFY(interface.isCanceled());
|
||||
QVERIFY(!f.isSuspending());
|
||||
QVERIFY(!f.isSuspended());
|
||||
QVERIFY(f.isCanceled());
|
||||
|
||||
interface.reportFinished();
|
||||
}
|
||||
@ -2715,7 +2780,14 @@ void tst_QFuture::testFutureTaken(QFuture<T> &noMoreFuture)
|
||||
QCOMPARE(noMoreFuture.resultCount(), 0);
|
||||
QCOMPARE(noMoreFuture.isStarted(), false);
|
||||
QCOMPARE(noMoreFuture.isRunning(), false);
|
||||
QCOMPARE(noMoreFuture.isSuspending(), false);
|
||||
QCOMPARE(noMoreFuture.isSuspended(), false);
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
QCOMPARE(noMoreFuture.isPaused(), false);
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
QCOMPARE(noMoreFuture.isFinished(), false);
|
||||
QCOMPARE(noMoreFuture.progressValue(), 0);
|
||||
}
|
||||
|
@ -57,9 +57,13 @@ private slots:
|
||||
void sharedFutureInterface();
|
||||
void changeFuture();
|
||||
void cancelEvents();
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
void pauseEvents();
|
||||
void pausedSuspendedOrder();
|
||||
#endif
|
||||
void suspendEvents();
|
||||
void suspended();
|
||||
void suspendedEvents();
|
||||
void suspendedEventsOrder();
|
||||
void finishedState();
|
||||
void throttling();
|
||||
void incrementalMapResults();
|
||||
@ -548,12 +552,21 @@ void callInterface(T &obj)
|
||||
obj.isFinished();
|
||||
obj.isRunning();
|
||||
obj.isCanceled();
|
||||
obj.isPaused();
|
||||
obj.isSuspended();
|
||||
obj.isSuspending();
|
||||
|
||||
obj.cancel();
|
||||
obj.pause();
|
||||
obj.suspend();
|
||||
obj.resume();
|
||||
obj.toggleSuspended();
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
obj.isPaused();
|
||||
obj.pause();
|
||||
obj.togglePaused();
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
obj.waitForFinished();
|
||||
|
||||
const T& objConst = obj;
|
||||
@ -566,7 +579,14 @@ void callInterface(T &obj)
|
||||
objConst.isFinished();
|
||||
objConst.isRunning();
|
||||
objConst.isCanceled();
|
||||
objConst.isSuspending();
|
||||
objConst.isSuspended();
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
objConst.isPaused();
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -665,6 +685,9 @@ void tst_QFutureWatcher::cancelEvents()
|
||||
QCOMPARE(resultReadySpy.count(), 0);
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
// Tests that events from paused futures are saved and
|
||||
// delivered on resume.
|
||||
void tst_QFutureWatcher::pauseEvents()
|
||||
@ -725,11 +748,120 @@ void tst_QFutureWatcher::pauseEvents()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QFutureWatcher::pausedSuspendedOrder()
|
||||
{
|
||||
QFutureInterface<void> iface;
|
||||
iface.reportStarted();
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
|
||||
QSignalSpy pausedSpy(&watcher, &QFutureWatcher<void>::paused);
|
||||
QVERIFY(pausedSpy.isValid());
|
||||
|
||||
QSignalSpy suspendedSpy(&watcher, &QFutureWatcher<void>::suspended);
|
||||
QVERIFY(suspendedSpy.isValid());
|
||||
|
||||
bool pausedBeforeSuspended = false;
|
||||
bool notSuspendedBeforePaused = false;
|
||||
connect(&watcher, &QFutureWatcher<void>::paused,
|
||||
[&] { notSuspendedBeforePaused = (suspendedSpy.count() == 0); });
|
||||
connect(&watcher, &QFutureWatcher<void>::suspended,
|
||||
[&] { pausedBeforeSuspended = (pausedSpy.count() == 1); });
|
||||
|
||||
watcher.setFuture(iface.future());
|
||||
iface.reportSuspended();
|
||||
|
||||
// Make sure reportPaused() is ignored if the state is not paused
|
||||
pausedSpy.wait(100);
|
||||
QCOMPARE(pausedSpy.count(), 0);
|
||||
QCOMPARE(suspendedSpy.count(), 0);
|
||||
|
||||
iface.setPaused(true);
|
||||
iface.reportSuspended();
|
||||
|
||||
QTRY_COMPARE(suspendedSpy.count(), 1);
|
||||
QCOMPARE(pausedSpy.count(), 1);
|
||||
QVERIFY(notSuspendedBeforePaused);
|
||||
QVERIFY(pausedBeforeSuspended);
|
||||
|
||||
iface.reportFinished();
|
||||
}
|
||||
QT_WARNING_POP
|
||||
#endif // QT_DEPRECATED_SINCE(6, 0)
|
||||
|
||||
// Tests that events from suspended futures are saved and
|
||||
// delivered on resume.
|
||||
void tst_QFutureWatcher::suspendEvents()
|
||||
{
|
||||
{
|
||||
QFutureInterface<int> iface;
|
||||
iface.reportStarted();
|
||||
|
||||
QFutureWatcher<int> watcher;
|
||||
|
||||
SignalSlotObject object;
|
||||
connect(&watcher, &QFutureWatcher<int>::resultReadyAt, &object,
|
||||
&SignalSlotObject::resultReadyAt);
|
||||
QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt);
|
||||
QVERIFY(resultReadySpy.isValid());
|
||||
|
||||
QSignalSpy suspendingSpy(&watcher, &QFutureWatcher<int>::suspending);
|
||||
QVERIFY(suspendingSpy.isValid());
|
||||
|
||||
watcher.setFuture(iface.future());
|
||||
watcher.suspend();
|
||||
|
||||
QTRY_COMPARE(suspendingSpy.count(), 1);
|
||||
|
||||
int value = 0;
|
||||
iface.reportFinished(&value);
|
||||
|
||||
// A result is reported, although the watcher is paused.
|
||||
// The corresponding event should be also reported.
|
||||
QTRY_COMPARE(resultReadySpy.count(), 1);
|
||||
|
||||
watcher.resume();
|
||||
}
|
||||
{
|
||||
QFutureInterface<int> iface;
|
||||
iface.reportStarted();
|
||||
|
||||
QFuture<int> a = iface.future();
|
||||
|
||||
QFutureWatcher<int> watcher;
|
||||
|
||||
SignalSlotObject object;
|
||||
connect(&watcher, &QFutureWatcher<int>::resultReadyAt, &object,
|
||||
&SignalSlotObject::resultReadyAt);
|
||||
QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt);
|
||||
QVERIFY(resultReadySpy.isValid());
|
||||
|
||||
watcher.setFuture(a);
|
||||
a.suspend();
|
||||
|
||||
int value = 0;
|
||||
iface.reportFinished(&value);
|
||||
|
||||
QFuture<int> b;
|
||||
watcher.setFuture(b); // If we watch b instead, resuming a
|
||||
a.resume(); // should give us no results.
|
||||
|
||||
QTest::qWait(10);
|
||||
QCOMPARE(resultReadySpy.count(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QFutureWatcher::suspended()
|
||||
{
|
||||
QFutureWatcher<void> watcher;
|
||||
QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt);
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
QSignalSpy pausedSpy(&watcher, &QFutureWatcher<int>::paused);
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
QSignalSpy suspendingSpy(&watcher, &QFutureWatcher<int>::suspending);
|
||||
QSignalSpy suspendedSpy(&watcher, &QFutureWatcher<int>::suspended);
|
||||
QSignalSpy finishedSpy(&watcher, &QFutureWatcher<int>::finished);
|
||||
|
||||
@ -748,13 +880,16 @@ void tst_QFutureWatcher::suspended()
|
||||
});
|
||||
watcher.setFuture(future);
|
||||
|
||||
// Allow some threads to start before pausing.
|
||||
// Allow some threads to start before suspending.
|
||||
QThread::msleep(200);
|
||||
|
||||
watcher.pause();
|
||||
watcher.pause();
|
||||
watcher.suspend();
|
||||
watcher.suspend();
|
||||
QTRY_COMPARE(suspendedSpy.count(), 1); // suspended() should be emitted only once
|
||||
QCOMPARE(suspendingSpy.count(), 2); // suspending() is emitted as many times as requested
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QCOMPARE(pausedSpy.count(), 2); // paused() is emitted as many times as requested
|
||||
#endif
|
||||
|
||||
// Make sure QFutureWatcher::resultReadyAt() is emitted only for already started threads.
|
||||
const auto resultReadyAfterPaused = resultReadySpy.count();
|
||||
@ -775,41 +910,41 @@ void tst_QFutureWatcher::suspended()
|
||||
QCOMPARE(resultReadySpy.count(), numValues - resultReadyAfterPaused);
|
||||
}
|
||||
|
||||
void tst_QFutureWatcher::suspendedEvents()
|
||||
void tst_QFutureWatcher::suspendedEventsOrder()
|
||||
{
|
||||
QFutureInterface<void> iface;
|
||||
iface.reportStarted();
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
|
||||
QSignalSpy pausedSpy(&watcher, &QFutureWatcher<void>::paused);
|
||||
QVERIFY(pausedSpy.isValid());
|
||||
QSignalSpy suspendingSpy(&watcher, &QFutureWatcher<void>::suspending);
|
||||
QVERIFY(suspendingSpy.isValid());
|
||||
|
||||
QSignalSpy suspendedSpy(&watcher, &QFutureWatcher<void>::suspended);
|
||||
QVERIFY(suspendedSpy.isValid());
|
||||
|
||||
bool pausedBeforeSuspended = false;
|
||||
bool notSuspendedBeforePasused = false;
|
||||
connect(&watcher, &QFutureWatcher<void>::paused,
|
||||
[&] { notSuspendedBeforePasused = (suspendedSpy.count() == 0); });
|
||||
bool suspendingBeforeSuspended = false;
|
||||
bool notSuspendedBeforeSuspending = false;
|
||||
connect(&watcher, &QFutureWatcher<void>::suspending,
|
||||
[&] { notSuspendedBeforeSuspending = (suspendedSpy.count() == 0); });
|
||||
connect(&watcher, &QFutureWatcher<void>::suspended,
|
||||
[&] { pausedBeforeSuspended = (pausedSpy.count() == 1); });
|
||||
[&] { suspendingBeforeSuspended = (suspendingSpy.count() == 1); });
|
||||
|
||||
watcher.setFuture(iface.future());
|
||||
iface.reportSuspended();
|
||||
|
||||
// Make sure reportPaused() is ignored if the state is not paused
|
||||
pausedSpy.wait(100);
|
||||
QCOMPARE(pausedSpy.count(), 0);
|
||||
suspendingSpy.wait(100);
|
||||
QCOMPARE(suspendingSpy.count(), 0);
|
||||
QCOMPARE(suspendedSpy.count(), 0);
|
||||
|
||||
iface.setPaused(true);
|
||||
iface.setSuspended(true);
|
||||
iface.reportSuspended();
|
||||
|
||||
QTRY_COMPARE(suspendedSpy.count(), 1);
|
||||
QCOMPARE(pausedSpy.count(), 1);
|
||||
QVERIFY(notSuspendedBeforePasused);
|
||||
QVERIFY(pausedBeforeSuspended);
|
||||
QCOMPARE(suspendingSpy.count(), 1);
|
||||
QVERIFY(notSuspendedBeforeSuspending);
|
||||
QVERIFY(suspendingBeforeSuspended);
|
||||
|
||||
iface.reportFinished();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user