From 9ffbc139d1b9ca780ca44ac1522d4bec624923c3 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Sun, 8 Nov 2015 23:26:43 +0200 Subject: QNativeSocketEngine: fix build in debug mode under Unix Change-Id: I197e4853cd3ddd7543bbdb12cecc19c0ed2c9ee2 Reviewed-by: Thiago Macieira --- src/network/socket/qnativesocketengine_unix.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/network/socket') diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index f1845f31f3..8626a6be0f 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -921,8 +921,10 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %lli, %s, %i) == %lli", data, qt_prettyDebug(data, qMin(recvResult, ssize_t(16)), recvResult).data(), maxSize, - address ? address->toString().toLatin1().constData() : "(nil)", - port ? *port : 0, (qint64) recvResult); + (recvResult != -1 && options != QAbstractSocketEngine::WantNone) + ? header->senderAddress.toString().toLatin1().constData() : "(unknown)", + (recvResult != -1 && options != QAbstractSocketEngine::WantNone) + ? header->senderPort : 0, (qint64) recvResult); #endif return qint64(maxSize ? recvResult : recvResult == -1 ? -1 : 0); @@ -1018,8 +1020,9 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEngine::sendDatagram(%p \"%s\", %lli, \"%s\", %i) == %lli", data, - qt_prettyDebug(data, qMin(len, 16), len).data(), len, host.toString().toLatin1().constData(), - port, (qint64) sentBytes); + qt_prettyDebug(data, qMin(len, 16), len).data(), len, + header.destinationAddress.toString().toLatin1().constData(), + header.destinationPort, (qint64) sentBytes); #endif return qint64(sentBytes); -- cgit v1.2.3 From b91389fef0d3c850dad17eab762d5c873f29a64d Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 10 Nov 2015 08:48:57 +0100 Subject: winrt: Clean up QNativeSocketEngine WinRT/Windows Phone "coding guidelines" are now used for the native socket engine as well. - Whenever an operation is expected to succeed Q_ASSERT_SUCCEEDED is used. - QWinRTFunctions::await is used for waiting for async operations - Improved error handling Change-Id: I6c8d64731da5c94b911a5190231c7c8f68d9c261 Reviewed-by: Andrew Knight --- src/network/socket/qnativesocketengine_winrt.cpp | 222 ++++++++++++----------- 1 file changed, 112 insertions(+), 110 deletions(-) (limited to 'src/network/socket') diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index d41bd4d313..cfb950592f 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -150,16 +150,10 @@ static AsyncStatus opStatus(const ComPtr &op) { ComPtr info; HRESULT hr = op.As(&info); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to cast op to IAsyncInfo."); - return Error; - } + Q_ASSERT_SUCCEEDED(hr); AsyncStatus status; hr = info->get_Status(&status); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to get AsyncStatus."); - return Error; - } + Q_ASSERT_SUCCEEDED(hr); return status; } @@ -265,25 +259,26 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) Q_D(QNativeSocketEngine); HStringReference hostNameRef(reinterpret_cast(name.utf16())); ComPtr hostNameFactory; - GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), - &hostNameFactory); + HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), + &hostNameFactory); + Q_ASSERT_SUCCEEDED(hr); ComPtr remoteHost; - if (FAILED(hostNameFactory->CreateHostName(hostNameRef.Get(), &remoteHost))) { - qWarning("QNativeSocketEnginePrivate::nativeConnect:: Could not create hostname"); - return false; - } + hr = hostNameFactory->CreateHostName(hostNameRef.Get(), &remoteHost); + RETURN_FALSE_IF_FAILED("QNativeSocketEngine::connectToHostByName: Could not create hostname."); const QString portString = QString::number(port); HStringReference portReference(reinterpret_cast(portString.utf16())); - HRESULT hr = E_FAIL; if (d->socketType == QAbstractSocket::TcpSocket) hr = d->tcpSocket()->ConnectAsync(remoteHost.Get(), portReference.Get(), &d->connectOp); else if (d->socketType == QAbstractSocket::UdpSocket) hr = d->udpSocket()->ConnectAsync(remoteHost.Get(), portReference.Get(), &d->connectOp); - if (FAILED(hr)) { - qWarning("QNativeSocketEnginePrivate::nativeConnect:: Could not obtain connect action"); + if (hr == E_ACCESSDENIED) { + qErrnoWarning(hr, "QNativeSocketEngine::connectToHostByName: Unable to connect to host. \ + Please check your manifest capabilities."); return false; } + Q_ASSERT_SUCCEEDED(hr); + d->socketState = QAbstractSocket::ConnectingState; hr = d->connectOp->put_Completed(Callback( d, &QNativeSocketEnginePrivate::handleConnectToHost).Get()); @@ -295,68 +290,52 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port) { Q_D(QNativeSocketEngine); + HRESULT hr; ComPtr hostAddress; + if (address != QHostAddress::Any && address != QHostAddress::AnyIPv4 && address != QHostAddress::AnyIPv6) { ComPtr hostNameFactory; - GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), + hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), &hostNameFactory); + Q_ASSERT_SUCCEEDED(hr); const QString addressString = address.toString(); HStringReference addressRef(reinterpret_cast(addressString.utf16())); - hostNameFactory->CreateHostName(addressRef.Get(), &hostAddress); + hr = hostNameFactory->CreateHostName(addressRef.Get(), &hostAddress); + RETURN_FALSE_IF_FAILED("QNativeSocketEngine::bind: Could not create hostname."); } - HRESULT hr; QString portQString = port ? QString::number(port) : QString(); HStringReference portString(reinterpret_cast(portQString.utf16())); ComPtr op; if (d->socketType == QAbstractSocket::TcpSocket) { - if (!d->tcpListener - && FAILED(RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocketListener).Get(), - &d->tcpListener))) { - qWarning("Failed to create listener"); - return false; + if (!d->tcpListener) { + hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocketListener).Get(), + &d->tcpListener); + Q_ASSERT_SUCCEEDED(hr); } - d->tcpListener->add_ConnectionReceived(Callback(d, &QNativeSocketEnginePrivate::handleClientConnection).Get(), &d->connectionToken); + hr = d->tcpListener->add_ConnectionReceived( + Callback(d, &QNativeSocketEnginePrivate::handleClientConnection).Get(), + &d->connectionToken); + Q_ASSERT_SUCCEEDED(hr); hr = d->tcpListener->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); - if (FAILED(hr)) { - qErrnoWarning(hr, "Unable to bind socket."); // ### Set error message - return false; - } } else if (d->socketType == QAbstractSocket::UdpSocket) { hr = d->udpSocket()->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); - if (FAILED(hr)) { - qErrnoWarning(hr, "Unable to bind socket."); // ### Set error message - return false; - } - hr = op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleBindCompleted).Get()); - if (FAILED(hr)) { - qErrnoWarning(hr, "Unable to set bind callback."); - return false; - } } - - if (op) { - while (opStatus(op) == Started) - d->eventLoop.processEvents(); - - AsyncStatus status = opStatus(op); - if (status == Error || status == Canceled) - return false; - - hr = op->GetResults(); - if (FAILED(hr)) { - qErrnoWarning(hr, "Failed to bind socket"); - return false; - } - - d->socketState = QAbstractSocket::BoundState; - d->fetchConnectionParameters(); - return true; + if (hr == E_ACCESSDENIED) { + qErrnoWarning(hr, "Unable to bind socket. Please check your manifest capabilities."); + return false; } + Q_ASSERT_SUCCEEDED(hr); - return false; + hr = op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleBindCompleted).Get()); + Q_ASSERT_SUCCEEDED(hr); + hr = QWinRTFunctions::await(op); + Q_ASSERT_SUCCEEDED(hr); + + d->socketState = QAbstractSocket::BoundState; + return d->fetchConnectionParameters(); } bool QNativeSocketEngine::listen() @@ -430,27 +409,36 @@ void QNativeSocketEngine::close() d->notifyOnWrite = false; d->notifyOnException = false; + HRESULT hr; if (d->connectOp) { ComPtr info; - d->connectOp.As(&info); + hr = d->connectOp.As(&info); + Q_ASSERT_SUCCEEDED(hr); if (info) { - info->Cancel(); - info->Close(); + hr = info->Cancel(); + Q_ASSERT_SUCCEEDED(hr); + hr = info->Close(); + Q_ASSERT_SUCCEEDED(hr); } } if (d->socketDescriptor != -1) { ComPtr socket; if (d->socketType == QAbstractSocket::TcpSocket) { - d->tcpSocket()->QueryInterface(IID_PPV_ARGS(&socket)); - d->tcpSocket()->Release(); + hr = d->tcpSocket()->QueryInterface(IID_PPV_ARGS(&socket)); + Q_ASSERT_SUCCEEDED(hr); + hr = d->tcpSocket()->Release(); + Q_ASSERT_SUCCEEDED(hr); } else if (d->socketType == QAbstractSocket::UdpSocket) { - d->udpSocket()->QueryInterface(IID_PPV_ARGS(&socket)); - d->udpSocket()->Release(); + hr = d->udpSocket()->QueryInterface(IID_PPV_ARGS(&socket)); + Q_ASSERT_SUCCEEDED(hr); + hr = d->udpSocket()->Release(); + Q_ASSERT_SUCCEEDED(hr); } if (socket) { - socket->Close(); + hr = socket->Close(); + Q_ASSERT_SUCCEEDED(hr); d->socketDescriptor = -1; } d->socketDescriptor = -1; @@ -531,7 +519,7 @@ qint64 QNativeSocketEngine::write(const char *data, qint64 len) hr = d->tcpSocket()->get_OutputStream(&stream); else if (d->socketType == QAbstractSocket::UdpSocket) hr = d->udpSocket()->get_OutputStream(&stream); - RETURN_IF_FAILED("Failed to get output stream to socket", return -1); + Q_ASSERT_SUCCEEDED(hr); qint64 bytesWritten = writeIOStream(stream, data, len); if (bytesWritten < 0) @@ -580,20 +568,21 @@ qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 len, const QI HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), &hostNameFactory); - RETURN_IF_FAILED("Could not obtain hostname factory", return -1); + Q_ASSERT_SUCCEEDED(hr); const QString addressString = header.destinationAddress.toString(); HStringReference hostNameRef(reinterpret_cast(addressString.utf16())); - hostNameFactory->CreateHostName(hostNameRef.Get(), &remoteHost); + hr = hostNameFactory->CreateHostName(hostNameRef.Get(), &remoteHost); + RETURN_IF_FAILED("QNativeSocketEngine::writeDatagram: Could not create hostname.", return -1); ComPtr> streamOperation; ComPtr stream; const QString portString = QString::number(header.destinationPort); HStringReference portRef(reinterpret_cast(portString.utf16())); hr = d->udpSocket()->GetOutputStreamAsync(remoteHost.Get(), portRef.Get(), &streamOperation); - RETURN_IF_FAILED("Failed to get output stream to socket", return -1); + Q_ASSERT_SUCCEEDED(hr); hr = QWinRTFunctions::await(streamOperation, stream.GetAddressOf()); - RETURN_IF_FAILED("Failed to get output stream to socket", return -1); + Q_ASSERT_SUCCEEDED(hr); return writeIOStream(stream, data, len); } @@ -778,26 +767,23 @@ void QNativeSocketEngine::establishRead() bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol) { Q_UNUSED(socketProtocol); + HRESULT hr; + switch (socketType) { case QAbstractSocket::TcpSocket: { ComPtr socket; - HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocket).Get(), &socket); - if (FAILED(hr)) { - qWarning("Failed to create StreamSocket instance"); - return false; - } + hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocket).Get(), &socket); + Q_ASSERT_SUCCEEDED(hr); socketDescriptor = qintptr(socket.Detach()); break; } case QAbstractSocket::UdpSocket: { ComPtr socket; - HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &socket); - if (FAILED(hr)) { - qWarning("Failed to create stream socket"); - return false; - } + hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &socket); + Q_ASSERT_SUCCEEDED(hr); socketDescriptor = qintptr(socket.Detach()); - udpSocket()->add_MessageReceived(Callback(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &connectionToken); + hr = udpSocket()->add_MessageReceived(Callback(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &connectionToken); + Q_ASSERT_SUCCEEDED(hr); break; } default: @@ -834,10 +820,12 @@ QNativeSocketEnginePrivate::~QNativeSocketEnginePrivate() if (socketDescriptor == -1 || connectionToken.value == -1) return; + HRESULT hr; if (socketType == QAbstractSocket::UdpSocket) - udpSocket()->remove_MessageReceived(connectionToken); + hr = udpSocket()->remove_MessageReceived(connectionToken); else if (socketType == QAbstractSocket::TcpSocket) - tcpListener->remove_ConnectionReceived(connectionToken); + hr = tcpListener->remove_ConnectionReceived(connectionToken); + Q_ASSERT_SUCCEEDED(hr); } void QNativeSocketEnginePrivate::setError(QAbstractSocket::SocketError error, ErrorString errorString) const @@ -1064,56 +1052,66 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() peerPort = 0; peerAddress.clear(); + HRESULT hr; if (socketType == QAbstractSocket::TcpSocket) { ComPtr hostName; HString tmpHString; ComPtr info; - if (FAILED(tcpSocket()->get_Information(&info))) { - qWarning("QNativeSocketEnginePrivate::fetchConnectionParameters: Could not obtain socket info"); - return false; - } - info->get_LocalAddress(&hostName); + hr = tcpSocket()->get_Information(&info); + Q_ASSERT_SUCCEEDED(hr); + hr = info->get_LocalAddress(&hostName); + Q_ASSERT_SUCCEEDED(hr); if (hostName) { - hostName->get_CanonicalName(tmpHString.GetAddressOf()); + hr = hostName->get_CanonicalName(tmpHString.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); localAddress.setAddress(qt_QStringFromHString(tmpHString)); - info->get_LocalPort(tmpHString.GetAddressOf()); + hr = info->get_LocalPort(tmpHString.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); localPort = qt_QStringFromHString(tmpHString).toInt(); } if (!localPort && tcpListener) { ComPtr listenerInfo = 0; - tcpListener->get_Information(&listenerInfo); - listenerInfo->get_LocalPort(tmpHString.GetAddressOf()); + hr = tcpListener->get_Information(&listenerInfo); + Q_ASSERT_SUCCEEDED(hr); + hr = listenerInfo->get_LocalPort(tmpHString.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); localPort = qt_QStringFromHString(tmpHString).toInt(); - localAddress == QHostAddress::Any; + localAddress = QHostAddress::Any; } info->get_RemoteAddress(&hostName); if (hostName) { - hostName->get_CanonicalName(tmpHString.GetAddressOf()); + hr = hostName->get_CanonicalName(tmpHString.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); peerAddress.setAddress(qt_QStringFromHString(tmpHString)); - info->get_RemotePort(tmpHString.GetAddressOf()); + hr = info->get_RemotePort(tmpHString.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); peerPort = qt_QStringFromHString(tmpHString).toInt(); } } else if (socketType == QAbstractSocket::UdpSocket) { ComPtr hostName; HString tmpHString; ComPtr info; - if (FAILED(udpSocket()->get_Information(&info))) { - qWarning("QNativeSocketEnginePrivate::fetchConnectionParameters: Could not obtain socket information"); - return false; - } - info->get_LocalAddress(&hostName); + hr = udpSocket()->get_Information(&info); + Q_ASSERT_SUCCEEDED(hr); + hr = info->get_LocalAddress(&hostName); + Q_ASSERT_SUCCEEDED(hr); if (hostName) { - hostName->get_CanonicalName(tmpHString.GetAddressOf()); + hr = hostName->get_CanonicalName(tmpHString.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); localAddress.setAddress(qt_QStringFromHString(tmpHString)); - info->get_LocalPort(tmpHString.GetAddressOf()); + hr = info->get_LocalPort(tmpHString.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); localPort = qt_QStringFromHString(tmpHString).toInt(); } - info->get_RemoteAddress(&hostName); + hr = info->get_RemoteAddress(&hostName); + Q_ASSERT_SUCCEEDED(hr); if (hostName) { - hostName->get_CanonicalName(tmpHString.GetAddressOf()); + hr = hostName->get_CanonicalName(tmpHString.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); peerAddress.setAddress(qt_QStringFromHString(tmpHString)); - info->get_RemotePort(tmpHString.GetAddressOf()); + hr = info->get_RemotePort(tmpHString.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); peerPort = qt_QStringFromHString(tmpHString).toInt(); } } @@ -1174,12 +1172,16 @@ void QNativeSocketEnginePrivate::handleConnectionEstablished(IAsyncAction *actio // The callback might be triggered several times if we do not cancel/reset it here if (connectOp) { ComPtr info; - connectOp.As(&info); + hr = connectOp.As(&info); + Q_ASSERT_SUCCEEDED(hr); if (info) { - info->Cancel(); - info->Close(); + hr = info->Cancel(); + Q_ASSERT_SUCCEEDED(hr); + hr = info->Close(); + Q_ASSERT_SUCCEEDED(hr); } - connectOp.Reset(); + hr = connectOp.Reset(); + Q_ASSERT_SUCCEEDED(hr); } socketState = QAbstractSocket::ConnectedState; -- cgit v1.2.3 From 08f9a1bd6ab9b1777ee5ba163d75e5c848c39eb4 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 10 Nov 2015 08:28:12 +0100 Subject: winrt: Fixed listening to tcp socket For some reason add_ConnectionReceived has to be called on the Xaml thread now. Otherwise the callback function won't be called and thus listening on a TCP socket won't work at all. Task-number: QTBUG-49121 Change-Id: I11ce2f72b0c1d3bb20e9579de5a2ce5150ca966a Reviewed-by: Andrew Knight Reviewed-by: Samuel Nevala Reviewed-by: Maurice Kalinowski --- src/network/socket/qnativesocketengine_winrt.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/network/socket') diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index cfb950592f..e9fa227733 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -47,11 +47,13 @@ #include #include +#include #ifndef QT_NO_SSL #include #endif +#include #include #include #include @@ -315,9 +317,11 @@ bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port) Q_ASSERT_SUCCEEDED(hr); } - hr = d->tcpListener->add_ConnectionReceived( - Callback(d, &QNativeSocketEnginePrivate::handleClientConnection).Get(), - &d->connectionToken); + hr = QEventDispatcherWinRT::runOnXamlThread([d]() { + return d->tcpListener->add_ConnectionReceived( + Callback(d, &QNativeSocketEnginePrivate::handleClientConnection).Get(), + &d->connectionToken); + }); Q_ASSERT_SUCCEEDED(hr); hr = d->tcpListener->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); } else if (d->socketType == QAbstractSocket::UdpSocket) { -- cgit v1.2.3