summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorOliver Wolff <oliver.wolff@theqtcompany.com>2016-04-06 10:42:05 +0200
committerOliver Wolff <oliver.wolff@theqtcompany.com>2016-04-11 11:22:41 +0000
commit14399b427cdb7662cbca6aa89443521301507b41 (patch)
tree15ee16f02d03b7341cfa0e0b52fddee8142d14ca /src
parent09487deeaea584b2abcc2b1049df2a8542bc113e (diff)
winrt: fix callbacks by moving them to the xaml thread
Change-Id: I7b4f007107e21c02646140acd5ebe5745ca79bce Reviewed-by: Maurice Kalinowski <maurice.kalinowski@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp118
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());