From 8853f2bad4c81bf7bc135da93da7a48d6936365d Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Fri, 28 Jul 2017 12:09:44 +0300 Subject: [PATCH] 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 Reviewed-by: Markus Goetz (Woboq GmbH) --- src/network/ssl/qsslsocket.cpp | 11 ++++++++++- src/network/ssl/qsslsocket_p.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 0e4b049353..9b62240767 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -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(); } diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index aec3437422..5e5a8d2371 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -217,6 +217,7 @@ private: protected: bool verifyErrorsHaveBeenIgnored(); bool paused; + bool flushTriggered; }; QT_END_NAMESPACE