QSslSocket: stabilize triggering for write

QSslSocket::writeData() accumulates outgoing data. It might be called
multiple times during the event processing (most likely from the long
loops which serialize the data).

As this function produces a notification event on each call, it's
possible to get a huge number of slot invocations on the next event
loop run, when we are interested in a single flush.

So, this patch protects the code against uncontrolled signal emission
that results in the lesser resource usage.

Change-Id: If7cf5b0e239abf0bd88a0dfaa8c1183cbd49e5ed
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Markus Goetz (Woboq GmbH) <markus@woboq.com>
This commit is contained in:
Alex Trotsenko 2017-07-28 12:09:44 +03:00
parent 5a1f1345aa
commit 8853f2bad4
2 changed files with 11 additions and 1 deletions

View File

@ -2015,7 +2015,10 @@ qint64 QSslSocket::writeData(const char *data, qint64 len)
d->writeBuffer.append(data, len);
// make sure we flush to the plain socket's buffer
QMetaObject::invokeMethod(this, "_q_flushWriteBuffer", Qt::QueuedConnection);
if (!d->flushTriggered) {
d->flushTriggered = true;
QMetaObject::invokeMethod(this, "_q_flushWriteBuffer", Qt::QueuedConnection);
}
return len;
}
@ -2034,6 +2037,7 @@ QSslSocketPrivate::QSslSocketPrivate()
, allowRootCertOnDemandLoading(true)
, plainSocket(0)
, paused(false)
, flushTriggered(false)
{
QSslConfigurationPrivate::deepCopyDefaultConfiguration(&configuration);
}
@ -2056,6 +2060,7 @@ void QSslSocketPrivate::init()
ignoreAllSslErrors = false;
shutdown = false;
pendingClose = false;
flushTriggered = false;
// we don't want to clear the ignoreErrorsList, so
// that it is possible setting it before connecting
@ -2512,6 +2517,10 @@ void QSslSocketPrivate::_q_channelBytesWrittenSlot(int channel, qint64 written)
void QSslSocketPrivate::_q_flushWriteBuffer()
{
Q_Q(QSslSocket);
// need to notice if knock-on effects of this flush (e.g. a readReady() via transmit())
// make another necessary, so clear flag before calling:
flushTriggered = false;
if (!writeBuffer.isEmpty())
q->flush();
}

View File

@ -217,6 +217,7 @@ private:
protected:
bool verifyErrorsHaveBeenIgnored();
bool paused;
bool flushTriggered;
};
QT_END_NAMESPACE