summaryrefslogtreecommitdiffstats
path: root/src/network/socket
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-06-20 14:09:00 +0200
committerLiang Qi <liang.qi@qt.io>2016-06-21 08:39:41 +0200
commitea438b2508f329698e11c6dae6994d441c6e67df (patch)
tree7a6052b98ba1ff6e0258c52cfc2726e197f53dd2 /src/network/socket
parenta2f319e9fb2f7595fc16d0d79e26438463051a53 (diff)
parent5f0ec7305e4310123ddeb98d3523087e3c560d9c (diff)
Merge remote-tracking branch 'origin/5.7' into dev
Conflicts: src/corelib/global/qglobal.cpp src/corelib/global/qsysinfo.h src/corelib/kernel/qcoreapplication_win.cpp src/gui/text/qdistancefield.cpp src/gui/text/qdistancefield_p.h src/plugins/platforms/windows/qwindowsglcontext.cpp src/plugins/platforms/windows/qwindowsglcontext.h Change-Id: Ib3500acc2b28553bde06758cd9a2e19eb7fe2978
Diffstat (limited to 'src/network/socket')
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp90
1 files changed, 57 insertions, 33 deletions
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp
index dd43615f98..9817d4c57d 100644
--- a/src/network/socket/qnativesocketengine_winrt.cpp
+++ b/src/network/socket/qnativesocketengine_winrt.cpp
@@ -259,31 +259,23 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket::
// Start processing incoming data
if (d->socketType == QAbstractSocket::TcpSocket) {
HRESULT hr;
- hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, this]() {
+ QEventDispatcherWinRT::runOnXamlThread([d, &hr, socket, this]() {
ComPtr<IBuffer> buffer;
HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer);
- RETURN_HR_IF_FAILED("initialize(): Could not create buffer");
-
+ RETURN_OK_IF_FAILED("initialize(): Could not create buffer");
ComPtr<IInputStream> stream;
hr = socket->get_InputStream(&stream);
- RETURN_HR_IF_FAILED("initialize(): Could not obtain input stream");
+ RETURN_OK_IF_FAILED("initialize(): Could not obtain input stream");
hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, d->readOp.GetAddressOf());
- if (FAILED(hr)) {
- qErrnoWarning(hr, "initialize(): Failed to read from the socket buffer (%s).",
+ RETURN_OK_IF_FAILED_WITH_ARGS("initialize(): Failed to read from the socket buffer (%s).",
socketDescription(this).constData());
- return E_FAIL;
- }
hr = d->readOp->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get());
- if (FAILED(hr)) {
- qErrnoWarning(hr, "initialize(): Failed to set socket read callback (%s).",
+ RETURN_OK_IF_FAILED_WITH_ARGS("initialize(): Failed to set socket read callback (%s).",
socketDescription(this).constData());
- return E_FAIL;
- }
return S_OK;
});
- if (hr == E_FAIL)
+ if (FAILED(hr))
return false;
- Q_ASSERT_SUCCEEDED(hr);
}
d->socketState = socketState;
@@ -335,11 +327,14 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port)
Q_ASSERT_SUCCEEDED(hr);
d->socketState = QAbstractSocket::ConnectingState;
- hr = QEventDispatcherWinRT::runOnXamlThread([d]() {
- return d->connectOp->put_Completed(Callback<IAsyncActionCompletedHandler>(
+ QEventDispatcherWinRT::runOnXamlThread([d, &hr]() {
+ hr = d->connectOp->put_Completed(Callback<IAsyncActionCompletedHandler>(
d, &QNativeSocketEnginePrivate::handleConnectOpFinished).Get());
+ RETURN_OK_IF_FAILED("connectToHostByName: Could not register \"connectOp\" callback");
+ return S_OK;
});
- Q_ASSERT_SUCCEEDED(hr);
+ if (FAILED(hr))
+ return false;
return d->socketState == QAbstractSocket::ConnectedState;
}
@@ -348,19 +343,21 @@ bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port)
{
Q_D(QNativeSocketEngine);
HRESULT hr;
- hr = QEventDispatcherWinRT::runOnXamlThread([address, d, port, this]() {
- HRESULT hr;
+ // runOnXamlThread may only return S_OK (will assert otherwise) so no need to check its result.
+ // hr is set inside the lambda though. If an error occurred hr will point that out.
+ bool specificErrorSet = false;
+ QEventDispatcherWinRT::runOnXamlThread([address, d, &hr, port, &specificErrorSet, this]() {
ComPtr<IHostName> hostAddress;
if (address != QHostAddress::Any && address != QHostAddress::AnyIPv4 && address != QHostAddress::AnyIPv6) {
ComPtr<IHostNameFactory> hostNameFactory;
hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(),
&hostNameFactory);
- RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not obtain hostname factory");
+ RETURN_OK_IF_FAILED("QNativeSocketEngine::bind: Could not obtain hostname factory");
const QString addressString = address.toString();
HStringReference addressRef(reinterpret_cast<LPCWSTR>(addressString.utf16()));
hr = hostNameFactory->CreateHostName(addressRef.Get(), &hostAddress);
- RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not create hostname.");
+ RETURN_OK_IF_FAILED("QNativeSocketEngine::bind: Could not create hostname.");
}
QString portQString = port ? QString::number(port) : QString();
@@ -371,13 +368,13 @@ bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port)
if (!d->tcpListener) {
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocketListener).Get(),
&d->tcpListener);
- RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not create tcp listener");
+ RETURN_OK_IF_FAILED("QNativeSocketEngine::bind: Could not create tcp listener");
}
hr = d->tcpListener->add_ConnectionReceived(
Callback<ClientConnectedHandler>(d, &QNativeSocketEnginePrivate::handleClientConnection).Get(),
&d->connectionToken);
- RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not register client connection callback");
+ RETURN_OK_IF_FAILED("QNativeSocketEngine::bind: Could not register client connection callback");
hr = d->tcpListener->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op);
} else if (d->socketType == QAbstractSocket::UdpSocket) {
hr = d->udpSocket()->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op);
@@ -385,15 +382,40 @@ bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port)
if (hr == E_ACCESSDENIED) {
qErrnoWarning(hr, "Unable to bind socket (%s:%hu/%s). Please check your manifest capabilities.",
qPrintable(address.toString()), port, socketDescription(this).constData());
- return hr;
+ d->setError(QAbstractSocket::SocketAccessError,
+ QNativeSocketEnginePrivate::AccessErrorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ specificErrorSet = true;
+ return S_OK;
}
- RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Unable to bind socket");
+ RETURN_OK_IF_FAILED("QNativeSocketEngine::bind: Unable to bind socket");
hr = QWinRTFunctions::await(op);
- RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not wait for bind to finish");
+ if (hr == 0x80072741) { // The requested address is not valid in its context
+ d->setError(QAbstractSocket::SocketAddressNotAvailableError,
+ QNativeSocketEnginePrivate::AddressNotAvailableErrorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ specificErrorSet = true;
+ return S_OK;
+ // Only one usage of each socket address (protocol/network address/port) is normally permitted
+ } else if (hr == 0x80072740) {
+ d->setError(QAbstractSocket::AddressInUseError,
+ QNativeSocketEnginePrivate::AddressInuseErrorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ specificErrorSet = true;
+ return S_OK;
+ }
+ RETURN_OK_IF_FAILED("QNativeSocketEngine::bind: Could not wait for bind to finish");
return S_OK;
});
- Q_ASSERT_SUCCEEDED(hr);
+ if (FAILED(hr)) {
+ if (!specificErrorSet) {
+ d->setError(QAbstractSocket::UnknownSocketError,
+ QNativeSocketEnginePrivate::UnknownSocketErrorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ }
+ return false;
+ }
d->socketState = QAbstractSocket::BoundState;
return d->fetchConnectionParameters();
@@ -853,20 +875,22 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
case QAbstractSocket::TcpSocket: {
ComPtr<IStreamSocket> socket;
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocket).Get(), &socket);
- Q_ASSERT_SUCCEEDED(hr);
+ RETURN_FALSE_IF_FAILED("createNewSocket: Could not create socket instance");
socketDescriptor = qintptr(socket.Detach());
break;
}
case QAbstractSocket::UdpSocket: {
ComPtr<IDatagramSocket> socket;
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &socket);
- Q_ASSERT_SUCCEEDED(hr);
+ RETURN_FALSE_IF_FAILED("createNewSocket: Could not create socket instance");
socketDescriptor = qintptr(socket.Detach());
- hr = QEventDispatcherWinRT::runOnXamlThread([this]() {
- HRESULT hr = udpSocket()->add_MessageReceived(Callback<DatagramReceivedHandler>(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &connectionToken);
- return hr;
+ QEventDispatcherWinRT::runOnXamlThread([&hr, this]() {
+ hr = udpSocket()->add_MessageReceived(Callback<DatagramReceivedHandler>(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &connectionToken);
+ RETURN_OK_IF_FAILED("createNewSocket: Could not add \"message received\" callback")
+ return S_OK;
});
- Q_ASSERT_SUCCEEDED(hr);
+ if (FAILED(hr))
+ return false;
break;
}
default: