summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorMårten Nordheim <marten.nordheim@qt.io>2022-02-08 14:28:25 +0100
committerMårten Nordheim <marten.nordheim@qt.io>2022-02-09 22:26:20 +0100
commit50c8ec9fa4f9925c825b70c581bd86034e1891d4 (patch)
tree85fc3b757bfe688a94ffc3fe6317cb2e9178f7bd /src/network
parentf3d89adf6dbb0ea2fa429197bfa59a6f107eb8e3 (diff)
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 Pick-to: 6.3 6.2 5.15 Change-Id: Ie524c48e11b6fa8010b78cc1bf3931efe2ce3351 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/network')
-rw-r--r--src/network/socket/qabstractsocket.cpp47
-rw-r--r--src/network/socket/qabstractsocket_p.h8
2 files changed, 41 insertions, 14 deletions
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 08e6b8c77d..b5228981fc 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@@ -1346,12 +1346,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)
@@ -1359,9 +1376,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 (std::exchange(priv->prePauseReadSocketNotifierState, false))
+ socketEngine->setReadNotificationEnabled(true);
+ if (std::exchange(priv->prePauseWriteSocketNotifierState, false))
+ socketEngine->setWriteNotificationEnabled(true);
+ if (std::exchange(priv->prePauseExceptionSocketNotifierState, false))
+ socketEngine->setExceptionNotificationEnabled(true);
}
QAbstractSocketEngine* QAbstractSocketPrivate::getSocketEngine(QAbstractSocket *socket)
diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h
index 83a8afe36d..d2a1378874 100644
--- a/src/network/socket/qabstractsocket_p.h
+++ b/src/network/socket/qabstractsocket_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -159,9 +159,9 @@ public:
QAbstractSocket::NetworkLayerProtocol preferredNetworkLayerProtocol;
- bool prePauseReadSocketNotifierState;
- bool prePauseWriteSocketNotifierState;
- bool prePauseExceptionSocketNotifierState;
+ bool prePauseReadSocketNotifierState = false;
+ bool prePauseWriteSocketNotifierState = false;
+ bool prePauseExceptionSocketNotifierState = false;
static void pauseSocketNotifiers(QAbstractSocket*);
static void resumeSocketNotifiers(QAbstractSocket*);
static QAbstractSocketEngine* getSocketEngine(QAbstractSocket*);