From ac2ccb1559c726f3b42473e915ef146714885213 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Wed, 11 May 2016 13:33:05 +0300 Subject: QHttpSocketEngine: set error on unsupported operations Force overloads which relate to UDP or listening to fail with a 'UnsupportedSocketOperationError' error code. Change-Id: I057c47864ee1d9c95b413edfda977dd0607844cb Reviewed-by: Timur Pocheptsov --- src/network/socket/qhttpsocketengine.cpp | 34 +++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'src/network/socket') diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp index 73b42ba432..f9ff958525 100644 --- a/src/network/socket/qhttpsocketengine.cpp +++ b/src/network/socket/qhttpsocketengine.cpp @@ -188,17 +188,26 @@ bool QHttpSocketEngine::connectToHostByName(const QString &hostname, quint16 por bool QHttpSocketEngine::bind(const QHostAddress &, quint16) { + qWarning("Operation is not supported"); + setError(QAbstractSocket::UnsupportedSocketOperationError, + QLatin1String("Unsupported socket operation")); return false; } bool QHttpSocketEngine::listen() { + qWarning("Operation is not supported"); + setError(QAbstractSocket::UnsupportedSocketOperationError, + QLatin1String("Unsupported socket operation")); return false; } int QHttpSocketEngine::accept() { - return 0; + qWarning("Operation is not supported"); + setError(QAbstractSocket::UnsupportedSocketOperationError, + QLatin1String("Unsupported socket operation")); + return -1; } void QHttpSocketEngine::close() @@ -251,16 +260,18 @@ qint64 QHttpSocketEngine::write(const char *data, qint64 len) bool QHttpSocketEngine::joinMulticastGroup(const QHostAddress &, const QNetworkInterface &) { + qWarning("Operation is not supported"); setError(QAbstractSocket::UnsupportedSocketOperationError, - QLatin1String("Operation on socket is not supported")); + QLatin1String("Unsupported socket operation")); return false; } bool QHttpSocketEngine::leaveMulticastGroup(const QHostAddress &, const QNetworkInterface &) { + qWarning("Operation is not supported"); setError(QAbstractSocket::UnsupportedSocketOperationError, - QLatin1String("Operation on socket is not supported")); + QLatin1String("Unsupported socket operation")); return false; } @@ -271,30 +282,39 @@ QNetworkInterface QHttpSocketEngine::multicastInterface() const bool QHttpSocketEngine::setMulticastInterface(const QNetworkInterface &) { + qWarning("Operation is not supported"); setError(QAbstractSocket::UnsupportedSocketOperationError, - QLatin1String("Operation on socket is not supported")); + QLatin1String("Unsupported socket operation")); return false; } #endif // QT_NO_NETWORKINTERFACE qint64 QHttpSocketEngine::readDatagram(char *, qint64, QIpPacketHeader *, PacketHeaderOptions) { - return 0; + qWarning("Operation is not supported"); + setError(QAbstractSocket::UnsupportedSocketOperationError, + QLatin1String("Unsupported socket operation")); + return -1; } qint64 QHttpSocketEngine::writeDatagram(const char *, qint64, const QIpPacketHeader &) { - return 0; + qWarning("Operation is not supported"); + setError(QAbstractSocket::UnsupportedSocketOperationError, + QLatin1String("Unsupported socket operation")); + return -1; } bool QHttpSocketEngine::hasPendingDatagrams() const { + qWarning("Operation is not supported"); return false; } qint64 QHttpSocketEngine::pendingDatagramSize() const { - return 0; + qWarning("Operation is not supported"); + return -1; } #endif // QT_NO_UDPSOCKET -- cgit v1.2.3 From 8714c99f65381af194cc4991c4258fec4b9a6307 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 13 May 2016 08:40:39 +0200 Subject: winrt: Fix potential crash when reading closed sockets Using multiple concurrent requests can cause a delay between a socket closing and getting deleted. At that point the state was closingDown, but not wasDeleted yet. Especially on slower arm devices, callbacks are done from another thread causing synchronization issues. Hence closingDown needs to be synced and handleReadyRead needs to have more criterias to return early to avoid invalid access crashes. Easiest to reproduce is heavy scrolling on the mapviewer example when it downloads a huge amount of tiles and cancels those requests when not in view anymore. Change-Id: I442b6243bbefb3af938b6b1b3739a6a85b4887c0 Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- src/network/socket/qnativesocketengine_winrt.cpp | 30 +++++++++++++++--------- src/network/socket/qnativesocketengine_winrt_p.h | 2 +- 2 files changed, 20 insertions(+), 12 deletions(-) (limited to 'src/network/socket') diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 599f37929c..d79dffa215 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -458,16 +458,21 @@ void QNativeSocketEngine::close() } #if _MSC_VER >= 1900 - // To close the connection properly (not with a hard reset) all pending read operation have to - // be finished or cancelled. The API isn't available on Windows 8.1 though. - ComPtr socket3; - hr = d->tcpSocket()->QueryInterface(IID_PPV_ARGS(&socket3)); - Q_ASSERT_SUCCEEDED(hr); + hr = QEventDispatcherWinRT::runOnXamlThread([d]() { + HRESULT hr; + // To close the connection properly (not with a hard reset) all pending read operation have to + // be finished or cancelled. The API isn't available on Windows 8.1 though. + ComPtr socket3; + hr = d->tcpSocket()->QueryInterface(IID_PPV_ARGS(&socket3)); + Q_ASSERT_SUCCEEDED(hr); - ComPtr action; - hr = socket3->CancelIOAsync(&action); - Q_ASSERT_SUCCEEDED(hr); - hr = QWinRTFunctions::await(action); + ComPtr action; + hr = socket3->CancelIOAsync(&action); + Q_ASSERT_SUCCEEDED(hr); + hr = QWinRTFunctions::await(action); + Q_ASSERT_SUCCEEDED(hr); + return S_OK; + }); Q_ASSERT_SUCCEEDED(hr); #endif // _MSC_VER >= 1900 @@ -1261,9 +1266,12 @@ void QNativeSocketEnginePrivate::handleConnectionEstablished(IAsyncAction *actio HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status) { - Q_Q(QNativeSocketEngine); - if (wasDeleted || isDeletingChildren) + if (closingDown || wasDeleted || isDeletingChildren + || socketState == QAbstractSocket::UnconnectedState) { return S_OK; + } + + Q_Q(QNativeSocketEngine); // A read in UnconnectedState will close the socket and return -1 and thus tell the caller, // that the connection was closed. The socket cannot be closed here, as the subsequent read diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index 4a5bc81769..2c1c42ecbc 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -148,7 +148,7 @@ public: qintptr socketDescriptor; bool notifyOnRead, notifyOnWrite, notifyOnException; - bool closingDown; + QAtomicInt closingDown; enum ErrorString { NonBlockingInitFailedErrorString, -- cgit v1.2.3 From 1675d9a1b23794592a55746dfebd6f40478fde03 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 6 Apr 2016 16:19:06 +0200 Subject: QLocalSocket/Win: use QRingBuffer::append Use QRingBuffer::append instead of an explicit reserve + memcpy. Change-Id: I237d1e43a377e156c148e89e410e15e400e1e426 Reviewed-by: Alex Trotsenko Reviewed-by: Oswald Buddenhagen --- src/network/socket/qlocalsocket_win.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/network/socket') diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 66b461522b..ca3b4e0d04 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -214,8 +214,7 @@ qint64 QLocalSocket::writeData(const char *data, qint64 len) Q_D(QLocalSocket); if (len == 0) return 0; - char *dest = d->writeBuffer.reserve(len); - memcpy(dest, data, len); + d->writeBuffer.append(data, len); if (!d->pipeWriter) { d->pipeWriter = new QWindowsPipeWriter(d->handle, this); connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten, -- cgit v1.2.3 From 082ee835b0e09f77e0e1bd061323a1b70178d202 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 6 Apr 2016 16:38:54 +0200 Subject: QLocalSocket/Win: Use QIODevice's internal write buffer Remove the extra write buffer from QLocalSocketPrivate and use QIODevice's new internal write buffer. Change-Id: I4297774ee89da2df59782adae8b804296e7f3301 Reviewed-by: Alex Trotsenko Reviewed-by: Oswald Buddenhagen --- src/network/socket/qlocalsocket_p.h | 2 -- src/network/socket/qlocalsocket_win.cpp | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src/network/socket') diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index cf36887e92..56f8b590f1 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -61,7 +61,6 @@ #if defined(QT_LOCALSOCKET_TCP) # include "qtcpsocket.h" #elif defined(Q_OS_WIN) -# include # include "private/qwindowspipereader_p.h" # include "private/qwindowspipewriter_p.h" # include @@ -134,7 +133,6 @@ public: void _q_pipeClosed(); void _q_winError(ulong windowsError, const QString &function); HANDLE handle; - QRingBuffer writeBuffer; QWindowsPipeWriter *pipeWriter; QWindowsPipeReader *pipeReader; QLocalSocket::LocalSocketError error; diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index ca3b4e0d04..bed4355aa9 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -107,6 +107,7 @@ QLocalSocketPrivate::QLocalSocketPrivate() : QIODevicePrivate(), error(QLocalSocket::UnknownSocketError), state(QLocalSocket::UnconnectedState) { + writeBufferChunkSize = QIODEVICE_BUFFERSIZE; } QLocalSocketPrivate::~QLocalSocketPrivate() @@ -232,7 +233,6 @@ void QLocalSocket::abort() if (d->pipeWriter) { delete d->pipeWriter; d->pipeWriter = 0; - d->writeBuffer.clear(); } close(); } @@ -290,6 +290,7 @@ void QLocalSocket::close() if (openMode() == NotOpen) return; + d->setWriteChannelCount(0); QIODevice::close(); d->serverName = QString(); d->fullServerName = QString(); -- cgit v1.2.3 From eba979f6956f8d74bf5a3cb6ed0d585396b790f1 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 18 May 2016 09:59:25 +0200 Subject: WinRT: Do not try to cancel IO for udp sockets on socket close As the functionality is not available for udp sockets trying to call it will cause a crash on socket close. Task-number: QTBUG-53424 Change-Id: Id80b36a248d12bf360135b2374c0a0efdab3a1f0 Reviewed-by: Maurice Kalinowski --- src/network/socket/qnativesocketengine_winrt.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'src/network/socket') diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 599f37929c..ecd364b84b 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -458,17 +458,19 @@ void QNativeSocketEngine::close() } #if _MSC_VER >= 1900 - // To close the connection properly (not with a hard reset) all pending read operation have to - // be finished or cancelled. The API isn't available on Windows 8.1 though. - ComPtr socket3; - hr = d->tcpSocket()->QueryInterface(IID_PPV_ARGS(&socket3)); - Q_ASSERT_SUCCEEDED(hr); + if (d->socketType == QAbstractSocket::TcpSocket) { + // To close the connection properly (not with a hard reset) all pending read operation have to + // be finished or cancelled. The API isn't available on Windows 8.1 though. + ComPtr socket3; + hr = d->tcpSocket()->QueryInterface(IID_PPV_ARGS(&socket3)); + Q_ASSERT_SUCCEEDED(hr); - ComPtr action; - hr = socket3->CancelIOAsync(&action); - Q_ASSERT_SUCCEEDED(hr); - hr = QWinRTFunctions::await(action); - Q_ASSERT_SUCCEEDED(hr); + ComPtr action; + hr = socket3->CancelIOAsync(&action); + Q_ASSERT_SUCCEEDED(hr); + hr = QWinRTFunctions::await(action); + Q_ASSERT_SUCCEEDED(hr); + } #endif // _MSC_VER >= 1900 if (d->readOp) { -- cgit v1.2.3