diff options
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/socket/qnativesocketengine_winrt.cpp | 72 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_winrt_p.h | 3 |
2 files changed, 48 insertions, 27 deletions
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 5e58ee3895..faea132b86 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -285,23 +285,11 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) return false; } d->socketState = QAbstractSocket::ConnectingState; - hr = QWinRTFunctions::await(d->connectOp); - RETURN_FALSE_IF_FAILED("Connection could not be established"); - bool connectionErrors = false; - d->handleConnectionErrors(d->connectOp.Get(), &connectionErrors); - if (connectionErrors) - return false; - d->connectOp.Reset(); - - d->socketState = QAbstractSocket::ConnectedState; - emit connectionReady(); + hr = d->connectOp->put_Completed(Callback<IAsyncActionCompletedHandler>( + d, &QNativeSocketEnginePrivate::handleConnectToHost).Get()); + Q_ASSERT_SUCCEEDED(hr); - // Delay the reader so that the SSL socket can upgrade - if (d->sslSocket) - connect(d->sslSocket, SIGNAL(encrypted()), SLOT(establishRead())); - else - establishRead(); - return true; + return d->socketState == QAbstractSocket::ConnectedState; } bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port) @@ -687,6 +675,14 @@ bool QNativeSocketEngine::waitForWrite(int msecs, bool *timedOut) { Q_UNUSED(msecs); Q_UNUSED(timedOut); + Q_D(QNativeSocketEngine); + if (d->socketState == QAbstractSocket::ConnectingState) { + HRESULT hr = QWinRTFunctions::await(d->connectOp, QWinRTFunctions::ProcessMainThreadEvents); + if (SUCCEEDED(hr)) { + d->handleConnectionEstablished(d->connectOp.Get()); + return true; + } + } return false; } @@ -727,7 +723,6 @@ void QNativeSocketEngine::setWriteNotificationEnabled(bool enable) if (bytesToWrite()) return; // will be emitted as a result of bytes written writeNotification(); - d->notifyOnWrite = false; } } @@ -1116,10 +1111,19 @@ HRESULT QNativeSocketEnginePrivate::handleClientConnection(IStreamSocketListener return S_OK; } -void QNativeSocketEnginePrivate::handleConnectionErrors(IAsyncAction *connectAction, bool *errorsOccured) +HRESULT QNativeSocketEnginePrivate::handleConnectToHost(IAsyncAction *action, AsyncStatus) { - bool error = true; - HRESULT hr = connectAction->GetResults(); + handleConnectionEstablished(action); + return S_OK; +} + +void QNativeSocketEnginePrivate::handleConnectionEstablished(IAsyncAction *action) +{ + Q_Q(QNativeSocketEngine); + if (wasDeleted || !connectOp) // Protect against a late callback + return; + + HRESULT hr = action->GetResults(); switch (hr) { case 0x8007274c: // A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString); @@ -1137,13 +1141,29 @@ void QNativeSocketEnginePrivate::handleConnectionErrors(IAsyncAction *connectAct if (FAILED(hr)) { setError(QAbstractSocket::UnknownSocketError, UnknownSocketErrorString); socketState = QAbstractSocket::UnconnectedState; - } else { - error = false; } break; } - if (errorsOccured) - *errorsOccured = error; + + // The callback might be triggered several times if we do not cancel/reset it here + if (connectOp) { + ComPtr<IAsyncInfo> info; + connectOp.As(&info); + if (info) { + info->Cancel(); + info->Close(); + } + connectOp.Reset(); + } + + socketState = QAbstractSocket::ConnectedState; + emit q->connectionReady(); + + // Delay the reader so that the SSL socket can upgrade + if (sslSocket) + QObject::connect(qobject_cast<QSslSocket *>(sslSocket), &QSslSocket::encrypted, q, &QNativeSocketEngine::establishRead); + else + q->establishRead(); } HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status) @@ -1163,7 +1183,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async hr = buffer->get_Length(&bufferLength); Q_ASSERT_SUCCEEDED(hr); if (!bufferLength) { - if (q->isReadNotificationEnabled()) + if (notifyOnRead) emit q->readReady(); return S_OK; } @@ -1187,7 +1207,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async readBytes.seek(readPos); readMutex.unlock(); - if (q->isReadNotificationEnabled()) + if (notifyOnRead) emit q->readReady(); ComPtr<IInputStream> stream; diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index eb032bc977..8e8448e6a8 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -216,7 +216,8 @@ private: ABI::Windows::Networking::Sockets::IDatagramSocketMessageReceivedEventArgs *args); HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener, ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args); - void handleConnectionErrors(ABI::Windows::Foundation::IAsyncAction *connectAction, bool *errorsOccured); + HRESULT handleConnectToHost(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus); + void handleConnectionEstablished(ABI::Windows::Foundation::IAsyncAction *action); HRESULT handleReadyRead(ABI::Windows::Foundation::IAsyncOperationWithProgress<ABI::Windows::Storage::Streams::IBuffer *, UINT32> *asyncInfo, ABI::Windows::Foundation::AsyncStatus); }; |