From 63b74e35e547afcc80fe4128a678badcaa9eb170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 8 Feb 2022 14:28:25 +0100 Subject: QAbstractSocket: Don't pretend pause and resume is a stack It only stores one layer of state, and pausing twice in a row will just overwrite the previous state. This doesn't happen often but can happen, especially on Windows if a certificate needs to be looked up in the system certificate stores (socket gets paused) and then a recoverable error occurs in QNAM (socket gets paused again). Fixes: QTBUG-100362 Fixes: QTBUG-63196 Fixes: QTBUG-98476 Change-Id: Ie524c48e11b6fa8010b78cc1bf3931efe2ce3351 Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov (cherry picked from commit 50c8ec9fa4f9925c825b70c581bd86034e1891d4) --- src/network/socket/qabstractsocket.cpp | 47 ++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 10 deletions(-) (limited to 'src/network/socket/qabstractsocket.cpp') diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 0237e0a57c..d1842badf3 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2021 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** @@ -1404,12 +1404,29 @@ void QAbstractSocketPrivate::pauseSocketNotifiers(QAbstractSocket *socket) QAbstractSocketEngine *socketEngine = socket->d_func()->socketEngine; if (!socketEngine) return; - socket->d_func()->prePauseReadSocketNotifierState = socketEngine->isReadNotificationEnabled(); - socket->d_func()->prePauseWriteSocketNotifierState = socketEngine->isWriteNotificationEnabled(); - socket->d_func()->prePauseExceptionSocketNotifierState = socketEngine->isExceptionNotificationEnabled(); - socketEngine->setReadNotificationEnabled(false); - socketEngine->setWriteNotificationEnabled(false); - socketEngine->setExceptionNotificationEnabled(false); + bool read = socketEngine->isReadNotificationEnabled(); + bool write = socketEngine->isWriteNotificationEnabled(); + bool except = socketEngine->isExceptionNotificationEnabled(); + +#ifdef QABSTRACTSOCKET_DEBUG + qDebug() << socketEngine->socketDescriptor() + << "pause notifiers, storing 'true' states, currently read:" << read + << "write:" << write << "except:" << except; +#endif + // We do this if-check to avoid accidentally overwriting any previously stored state + // It will reset to false once the socket is re-enabled. + if (read) { + socket->d_func()->prePauseReadSocketNotifierState = true; + socketEngine->setReadNotificationEnabled(false); + } + if (write) { + socket->d_func()->prePauseWriteSocketNotifierState = true; + socketEngine->setWriteNotificationEnabled(false); + } + if (except) { + socket->d_func()->prePauseExceptionSocketNotifierState = true; + socketEngine->setExceptionNotificationEnabled(false); + } } void QAbstractSocketPrivate::resumeSocketNotifiers(QAbstractSocket *socket) @@ -1417,9 +1434,19 @@ void QAbstractSocketPrivate::resumeSocketNotifiers(QAbstractSocket *socket) QAbstractSocketEngine *socketEngine = socket->d_func()->socketEngine; if (!socketEngine) return; - socketEngine->setReadNotificationEnabled(socket->d_func()->prePauseReadSocketNotifierState); - socketEngine->setWriteNotificationEnabled(socket->d_func()->prePauseWriteSocketNotifierState); - socketEngine->setExceptionNotificationEnabled(socket->d_func()->prePauseExceptionSocketNotifierState); + QAbstractSocketPrivate *priv = socket->d_func(); +#ifdef QABSTRACTSOCKET_DEBUG + qDebug() << socketEngine->socketDescriptor() + << "Maybe resume notifiers, read:" << priv->prePauseReadSocketNotifierState + << "write:" << priv->prePauseWriteSocketNotifierState + << "exception:" << priv->prePauseExceptionSocketNotifierState; +#endif + if (qExchange(priv->prePauseReadSocketNotifierState, false)) + socketEngine->setReadNotificationEnabled(true); + if (qExchange(priv->prePauseWriteSocketNotifierState, false)) + socketEngine->setWriteNotificationEnabled(true); + if (qExchange(priv->prePauseExceptionSocketNotifierState, false)) + socketEngine->setExceptionNotificationEnabled(true); } QAbstractSocketEngine* QAbstractSocketPrivate::getSocketEngine(QAbstractSocket *socket) -- cgit v1.2.3 From a2c85c8f5f008d150775fdeff6a6723160237368 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sat, 9 Oct 2021 19:24:05 +0200 Subject: network: Fix typos in documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I386c6e4a21dacb2553a39a073052dcf6d92a9854 Reviewed-by: Giuseppe D'Angelo Reviewed-by: MÃ¥rten Nordheim (cherry picked from commit 72c7c96143ecfe5544fdb66946c8d3c237f7c15e) --- src/network/socket/qabstractsocket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/network/socket/qabstractsocket.cpp') diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index d1842badf3..d666d92d5d 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -437,7 +437,7 @@ \value DontShareAddress Bind the address and port exclusively, so that no other services are allowed to rebind. By passing this option to - QAbstractSocket::bind(), you are guaranteed that on successs, your service + QAbstractSocket::bind(), you are guaranteed that on success, your service is the only one that listens to the address and port. No services are allowed to rebind, even if they pass ReuseAddressHint. This option provides more security than ShareAddress, but on certain operating -- cgit v1.2.3