diff options
author | Oliver Wolff <oliver.wolff@theqtcompany.com> | 2016-04-06 10:42:05 +0200 |
---|---|---|
committer | Oliver Wolff <oliver.wolff@theqtcompany.com> | 2016-04-11 11:22:41 +0000 |
commit | 14399b427cdb7662cbca6aa89443521301507b41 (patch) | |
tree | 15ee16f02d03b7341cfa0e0b52fddee8142d14ca | |
parent | 09487deeaea584b2abcc2b1049df2a8542bc113e (diff) |
winrt: fix callbacks by moving them to the xaml thread
Change-Id: I7b4f007107e21c02646140acd5ebe5745ca79bce
Reviewed-by: Maurice Kalinowski <maurice.kalinowski@theqtcompany.com>
-rw-r--r-- | src/network/socket/qnativesocketengine_winrt.cpp | 118 |
1 files changed, 67 insertions, 51 deletions
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 35b7d5474b..d1ebd19cca 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -298,8 +298,10 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) Q_ASSERT_SUCCEEDED(hr); d->socketState = QAbstractSocket::ConnectingState; - hr = d->connectOp->put_Completed(Callback<IAsyncActionCompletedHandler>( + hr = QEventDispatcherWinRT::runOnXamlThread([d]() { + return d->connectOp->put_Completed(Callback<IAsyncActionCompletedHandler>( d, &QNativeSocketEnginePrivate::handleConnectToHost).Get()); + }); Q_ASSERT_SUCCEEDED(hr); return d->socketState == QAbstractSocket::ConnectedState; @@ -309,50 +311,53 @@ bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port) { Q_D(QNativeSocketEngine); HRESULT hr; - ComPtr<IHostName> hostAddress; + hr = QEventDispatcherWinRT::runOnXamlThread([address, d, port, this]() { + HRESULT hr; + 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); - Q_ASSERT_SUCCEEDED(hr); - const QString addressString = address.toString(); - HStringReference addressRef(reinterpret_cast<LPCWSTR>(addressString.utf16())); - hr = hostNameFactory->CreateHostName(addressRef.Get(), &hostAddress); - RETURN_FALSE_IF_FAILED("QNativeSocketEngine::bind: Could not create hostname."); - } + 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"); + 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."); + } - QString portQString = port ? QString::number(port) : QString(); - HStringReference portString(reinterpret_cast<LPCWSTR>(portQString.utf16())); + QString portQString = port ? QString::number(port) : QString(); + HStringReference portString(reinterpret_cast<LPCWSTR>(portQString.utf16())); - ComPtr<IAsyncAction> op; - if (d->socketType == QAbstractSocket::TcpSocket) { - if (!d->tcpListener) { - hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocketListener).Get(), - &d->tcpListener); - Q_ASSERT_SUCCEEDED(hr); - } + ComPtr<IAsyncAction> op; + if (d->socketType == QAbstractSocket::TcpSocket) { + 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"); + } - hr = QEventDispatcherWinRT::runOnXamlThread([d]() { - return d->tcpListener->add_ConnectionReceived( + hr = d->tcpListener->add_ConnectionReceived( Callback<ClientConnectedHandler>(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) { - hr = d->udpSocket()->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); - } - 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 false; - } - Q_ASSERT_SUCCEEDED(hr); + RETURN_HR_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); + } + 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; + } + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Unable to bind socket"); - hr = op->put_Completed(Callback<IAsyncActionCompletedHandler>(d, &QNativeSocketEnginePrivate::handleBindCompleted).Get()); - Q_ASSERT_SUCCEEDED(hr); - hr = QWinRTFunctions::await(op); + hr = op->put_Completed(Callback<IAsyncActionCompletedHandler>(d, &QNativeSocketEnginePrivate::handleBindCompleted).Get()); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not register bind callback"); + hr = QWinRTFunctions::await(op); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not wait for bind to finish"); + return S_OK; + }); Q_ASSERT_SUCCEEDED(hr); d->socketState = QAbstractSocket::BoundState; @@ -404,7 +409,9 @@ int QNativeSocketEngine::accept() socketDescription(this).constData()); return -1; } - hr = op->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + hr = QEventDispatcherWinRT::runOnXamlThread([d, op]() { + return op->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + }); if (FAILED(hr)) { qErrnoWarning(hr, "accept(): Failed to set socket read callback (%s).", socketDescription(this).constData()); @@ -774,18 +781,22 @@ void QNativeSocketEngine::establishRead() Q_D(QNativeSocketEngine); HRESULT hr; - ComPtr<IInputStream> stream; - hr = d->tcpSocket()->get_InputStream(&stream); - RETURN_VOID_IF_FAILED("Failed to get socket input stream"); + hr = QEventDispatcherWinRT::runOnXamlThread([d]() { + ComPtr<IInputStream> stream; + HRESULT hr = d->tcpSocket()->get_InputStream(&stream); + RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to get socket input stream"); - ComPtr<IBuffer> buffer; - hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); - Q_ASSERT_SUCCEEDED(hr); + ComPtr<IBuffer> buffer; + hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); + RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to create buffer"); - ComPtr<IAsyncBufferOperation> op; - hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, &op); - RETURN_VOID_IF_FAILED("Failed to initiate socket read"); - hr = op->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + ComPtr<IAsyncBufferOperation> op; + hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, &op); + RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to initiate socket read"); + hr = op->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to register read callback"); + return S_OK; + }); Q_ASSERT_SUCCEEDED(hr); } @@ -807,7 +818,10 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &socket); Q_ASSERT_SUCCEEDED(hr); socketDescriptor = qintptr(socket.Detach()); - hr = udpSocket()->add_MessageReceived(Callback<DatagramReceivedHandler>(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &connectionToken); + hr = QEventDispatcherWinRT::runOnXamlThread([this]() { + HRESULT hr = udpSocket()->add_MessageReceived(Callback<DatagramReceivedHandler>(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &connectionToken); + return hr; + }); Q_ASSERT_SUCCEEDED(hr); break; } @@ -1297,7 +1311,9 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async socketDescription(q).constData()); return S_OK; } - hr = op->put_Completed(Callback<SocketReadCompletedHandler>(this, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + hr = QEventDispatcherWinRT::runOnXamlThread([op, this]() { + return op->put_Completed(Callback<SocketReadCompletedHandler>(this, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + }); if (FAILED(hr)) { qErrnoWarning(hr, "handleReadyRead(): Failed to set socket read callback (%s).", socketDescription(q).constData()); |