summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSona Kurazyan <sona.kurazyan@qt.io>2021-06-08 16:52:00 +0200
committerSona Kurazyan <sona.kurazyan@qt.io>2021-06-12 03:08:59 +0200
commit02f521a59cb008a6900b79139b21a5eabaeb66ee (patch)
tree0887ce38a39205ddb4dce2f2977f2ec46ad5596f
parent6460c3c33d8f880c50e2b529827437e442d05bd3 (diff)
Allocate progress related data on demand
Some of the data members related to progress reporting (min, max and text) aren't used when user doesn't want manual progress reporting, so the data for them can be allocated on demand, when the user explicitly sets them. Note, that we still need to always create other related data (current value and progress timer), since in the non-manual mode progress is still reported by incrementing the current value each time a new result is reported. Task-number: QTBUG-92045 Change-Id: I1e5bd17de2613a6ea72ccff0029812f67686708b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
-rw-r--r--src/corelib/thread/qfutureinterface.cpp76
-rw-r--r--src/corelib/thread/qfutureinterface_p.h15
2 files changed, 62 insertions, 29 deletions
diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp
index 35883d71e1..b34385897c 100644
--- a/src/corelib/thread/qfutureinterface.cpp
+++ b/src/corelib/thread/qfutureinterface.cpp
@@ -299,13 +299,13 @@ int QFutureInterfaceBase::progressValue() const
int QFutureInterfaceBase::progressMinimum() const
{
const QMutexLocker lock(&d->m_mutex);
- return d->m_progressMinimum;
+ return d->m_progress ? d->m_progress->minimum : 0;
}
int QFutureInterfaceBase::progressMaximum() const
{
const QMutexLocker lock(&d->m_mutex);
- return d->m_progressMaximum;
+ return d->m_progress ? d->m_progress->maximum : 0;
}
int QFutureInterfaceBase::resultCount() const
@@ -317,7 +317,7 @@ int QFutureInterfaceBase::resultCount() const
QString QFutureInterfaceBase::progressText() const
{
QMutexLocker locker(&d->m_mutex);
- return d->m_progressText;
+ return d->m_progress ? d->m_progress->text : QString();
}
bool QFutureInterfaceBase::isProgressUpdateNeeded() const
@@ -382,7 +382,7 @@ void QFutureInterfaceBase::reportFinished()
void QFutureInterfaceBase::setExpectedResultCount(int resultCount)
{
- if (d->manualProgress == false)
+ if (d->m_progress)
setProgressRange(0, resultCount);
d->m_expectedResultCount = resultCount;
}
@@ -455,8 +455,8 @@ void QFutureInterfaceBase::reportResultsReady(int beginIndex, int endIndex)
d->waitCondition.wakeAll();
- if (d->manualProgress == false) {
- if (d->internal_updateProgress(d->m_progressValue + endIndex - beginIndex) == false) {
+ if (!d->m_progress) {
+ if (d->internal_updateProgressValue(d->m_progressValue + endIndex - beginIndex) == false) {
d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::ResultsReady,
beginIndex,
endIndex));
@@ -465,7 +465,7 @@ void QFutureInterfaceBase::reportResultsReady(int beginIndex, int endIndex)
d->sendCallOuts(QFutureCallOutEvent(QFutureCallOutEvent::Progress,
d->m_progressValue,
- d->m_progressText),
+ QString()),
QFutureCallOutEvent(QFutureCallOutEvent::ResultsReady,
beginIndex,
endIndex));
@@ -515,8 +515,10 @@ void QFutureInterfaceBase::setFilterMode(bool enable)
void QFutureInterfaceBase::setProgressRange(int minimum, int maximum)
{
QMutexLocker locker(&d->m_mutex);
- d->m_progressMinimum = minimum;
- d->m_progressMaximum = qMax(minimum, maximum);
+ if (!d->m_progress)
+ d->m_progress.reset(new QFutureInterfaceBasePrivate::ProgressData());
+ d->m_progress->minimum = minimum;
+ d->m_progress->maximum = qMax(minimum, maximum);
d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::ProgressRange, minimum, maximum));
d->m_progressValue = minimum;
}
@@ -536,12 +538,12 @@ void QFutureInterfaceBase::setProgressValueAndText(int progressValue,
const QString &progressText)
{
QMutexLocker locker(&d->m_mutex);
- if (d->manualProgress == false)
- d->manualProgress = true;
+ if (!d->m_progress)
+ d->m_progress.reset(new QFutureInterfaceBasePrivate::ProgressData());
- const bool useProgressRange = (d->m_progressMaximum != 0) || (d->m_progressMinimum != 0);
+ const bool useProgressRange = (d->m_progress->maximum != 0) || (d->m_progress->minimum != 0);
if (useProgressRange
- && ((progressValue < d->m_progressMinimum) || (progressValue > d->m_progressMaximum))) {
+ && ((progressValue < d->m_progress->minimum) || (progressValue > d->m_progress->maximum))) {
return;
}
@@ -554,7 +556,7 @@ void QFutureInterfaceBase::setProgressValueAndText(int progressValue,
if (d->internal_updateProgress(progressValue, progressText)) {
d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Progress,
d->m_progressValue,
- d->m_progressText));
+ d->m_progress->text));
}
}
@@ -613,8 +615,7 @@ bool QFutureInterfaceBase::derefT() const noexcept
void QFutureInterfaceBase::reset()
{
d->m_progressValue = 0;
- d->m_progressMinimum = 0;
- d->m_progressMaximum = 0;
+ d->m_progress.reset();
d->setState(QFutureInterfaceBase::NoState);
d->progressTime.invalidate();
d->isValid = false;
@@ -666,16 +667,34 @@ bool QFutureInterfaceBasePrivate::internal_waitForNextResult()
&& data.m_results.hasNextResult();
}
+bool QFutureInterfaceBasePrivate::internal_updateProgressValue(int progress)
+{
+ if (m_progressValue >= progress)
+ return false;
+
+ m_progressValue = progress;
+
+ if (progressTime.isValid() && m_progressValue != 0) // make sure the first and last steps are emitted.
+ if (progressTime.elapsed() < (1000 / MaxProgressEmitsPerSecond))
+ return false;
+
+ progressTime.start();
+ return true;
+
+}
+
bool QFutureInterfaceBasePrivate::internal_updateProgress(int progress,
const QString &progressText)
{
if (m_progressValue >= progress)
return false;
+ Q_ASSERT(m_progress);
+
m_progressValue = progress;
- m_progressText = progressText;
+ m_progress->text = progressText;
- if (progressTime.isValid() && m_progressValue != m_progressMaximum) // make sure the first and last steps are emitted.
+ if (progressTime.isValid() && m_progressValue != m_progress->maximum) // make sure the first and last steps are emitted.
if (progressTime.elapsed() < (1000 / MaxProgressEmitsPerSecond))
return false;
@@ -733,12 +752,21 @@ void QFutureInterfaceBasePrivate::connectOutputInterface(QFutureCallOutInterface
const auto currentState = state.loadRelaxed();
if (currentState & QFutureInterfaceBase::Started) {
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Started));
- interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::ProgressRange,
- m_progressMinimum,
- m_progressMaximum));
- interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Progress,
- m_progressValue,
- m_progressText));
+ if (m_progress) {
+ interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::ProgressRange,
+ m_progress->minimum,
+ m_progress->maximum));
+ interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Progress,
+ m_progressValue,
+ m_progress->text));
+ } else {
+ interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::ProgressRange,
+ 0,
+ 0));
+ interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Progress,
+ m_progressValue,
+ QString()));
+ }
}
if (!hasException) {
diff --git a/src/corelib/thread/qfutureinterface_p.h b/src/corelib/thread/qfutureinterface_p.h
index a717a1143f..3a4dd076d8 100644
--- a/src/corelib/thread/qfutureinterface_p.h
+++ b/src/corelib/thread/qfutureinterface_p.h
@@ -184,7 +184,6 @@ public:
};
Data data = { QtPrivate::ResultStoreBase() };
- QString m_progressText;
QRunnable *runnable = nullptr;
QThreadPool *m_pool = nullptr;
// Wrapper for continuation
@@ -192,11 +191,17 @@ public:
RefCount refCount = 1;
QAtomicInt state; // reads and writes can happen unprotected, both must be atomic
+
int m_progressValue = 0; // TQ
- int m_progressMinimum = 0; // TQ
- int m_progressMaximum = 0; // TQ
+ struct ProgressData
+ {
+ int minimum = 0; // TQ
+ int maximum = 0; // TQ
+ QString text;
+ };
+ QScopedPointer<ProgressData> m_progress;
+
int m_expectedResultCount = 0;
- bool manualProgress = false; // only accessed from executing thread
bool launchAsync = false;
bool isValid = false;
bool hasException = false;
@@ -209,6 +214,7 @@ public:
int internal_resultCount() const;
bool internal_isResultReadyAt(int index) const;
bool internal_waitForNextResult();
+ bool internal_updateProgressValue(int progress);
bool internal_updateProgress(int progress, const QString &progressText = QString());
void internal_setThrottled(bool enable);
void sendCallOut(const QFutureCallOutEvent &callOut);
@@ -217,7 +223,6 @@ public:
void disconnectOutputInterface(QFutureCallOutInterface *iface);
void setState(QFutureInterfaceBase::State state);
-
};
QT_END_NAMESPACE