summaryrefslogtreecommitdiffstats
path: root/src/network/socket
diff options
context:
space:
mode:
authorOliver Wolff <oliver.wolff@theqtcompany.com>2015-06-23 12:59:34 +0200
committerOliver Wolff <oliver.wolff@theqtcompany.com>2015-09-03 12:13:41 +0000
commit055cbaafd6c48ddfd00f918006c0a2ffe3a72f81 (patch)
treebb0e592cce2c0d17ddd905bc7162028bae86a470 /src/network/socket
parent111ee58c065602bfcde520b54f44809d854e73f0 (diff)
Fixed connectToHost
connectToHost is not meant to be synchronous, but waitForWrite is used internally to wait for the connection to be established. Thus the same logic that is used in the callback has to be applied in there. Task-number: QTBUG-46339 Change-Id: Ia1fb5c1ae609a9942ff4d8fe2f5fab2ef572da0c Reviewed-by: Andrew Knight <andrew.knight@intopalo.com>
Diffstat (limited to 'src/network/socket')
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp72
-rw-r--r--src/network/socket/qnativesocketengine_winrt_p.h3
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);
};