winrt: Register for socket reads for correct socket engine

Reading from the socket must not happen from the managing socket engine
but the socket engines that are spawned for reading/writing data (these
are initialized with the socket descriptor given). With the current
implementation the managing socket engine might be closed after the
first connection so that no other socket requests will be handled.

Change-Id: I76e1356bb75b8641b4f113872be143ca5c8b08cc
Reviewed-by: Samuel Nevala <samuel.nevala@intopalo.com>
Reviewed-by: Maurice Kalinowski <maurice.kalinowski@theqtcompany.com>
This commit is contained in:
Oliver Wolff 2016-04-07 15:52:59 +02:00
parent 29a8c2d9b9
commit b501fc3b33

View File

@ -239,7 +239,8 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket::
close();
// Currently, only TCP sockets are initialized this way.
d->socketDescriptor = qintptr(gSocketHandler->pendingTcpSockets.take(socketDescriptor));
IStreamSocket *socket = gSocketHandler->pendingTcpSockets.take(socketDescriptor);
d->socketDescriptor = qintptr(socket);
d->socketType = QAbstractSocket::TcpSocket;
if (!d->socketDescriptor || !d->fetchConnectionParameters()) {
@ -249,6 +250,36 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket::
return false;
}
// Start processing incoming data
if (d->socketType == QAbstractSocket::TcpSocket) {
HRESULT hr;
hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, this]() {
ComPtr<IBuffer> buffer;
HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer);
RETURN_HR_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");
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).",
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).",
socketDescription(this).constData());
return E_FAIL;
}
return S_OK;
});
if (hr == E_FAIL)
return false;
Q_ASSERT_SUCCEEDED(hr);
}
d->socketState = socketState;
return true;
}
@ -390,37 +421,9 @@ int QNativeSocketEngine::accept()
return -1;
}
// Start processing incoming data
if (d->socketType == QAbstractSocket::TcpSocket) {
IStreamSocket *socket = d->pendingConnections.takeFirst();
HRESULT hr;
hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, this]() {
ComPtr<IBuffer> buffer;
HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer);
RETURN_HR_IF_FAILED("accept(): Could not create buffer");
ComPtr<IInputStream> stream;
hr = socket->get_InputStream(&stream);
RETURN_HR_IF_FAILED("accept(): Could not obtain input stream");
hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, &d->readOp);
if (FAILED(hr)) {
qErrnoWarning(hr, "accept(): 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, "accept(): Failed to set socket read callback (%s).",
socketDescription(this).constData());
return E_FAIL;
}
return S_OK;
});
if (hr == E_FAIL)
return -1;
Q_ASSERT_SUCCEEDED(hr);
d->currentConnections.append(socket);
SocketHandler *handler = gSocketHandler();
handler->pendingTcpSockets.insert(++handler->socketCount, socket);
return handler->socketCount;