winrt: fix callbacks by moving them to the xaml thread
Change-Id: I7b4f007107e21c02646140acd5ebe5745ca79bce Reviewed-by: Maurice Kalinowski <maurice.kalinowski@theqtcompany.com>
This commit is contained in:
parent
09487deeae
commit
14399b427c
@ -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.");
|
||||
}
|
||||
|
||||
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);
|
||||
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.");
|
||||
}
|
||||
|
||||
hr = QEventDispatcherWinRT::runOnXamlThread([d]() {
|
||||
return d->tcpListener->add_ConnectionReceived(
|
||||
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);
|
||||
RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not create tcp listener");
|
||||
}
|
||||
|
||||
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());
|
||||
|
Loading…
Reference in New Issue
Block a user