Reputation: 10661
This error occurred in this snippet:
void TCPConnectThread::run()
{
m_socket = new QTcpSocket();
m_socket->setSocketDescriptor(m_fd);
m_socket->waitForReadyRead(10000);
QString data = m_socket->readAll();
m_socket->waitForDisconnected();
}
A little deep in:
if (::WSAIoctl(socketDescriptor, FIONREAD, &dummy, sizeof(dummy), &nbytes,
sizeof(nbytes), &sizeWritten, 0,0) == SOCKET_ERROR) <-Exception here
{
WS_ERROR_DEBUG(WSAGetLastError());
return -1;
}
Deeper in:
if (::getsockopt(d->socketDescriptor, SOL_SOCKET,
SO_ERROR, (char *) &value, &valueSize) == 0) <-Here
invalid handle
exception occurred when exiting the run
method.
Here's how I get m_socket:
m_socket = new QTcpSocket();
m_socket->setSocketDescriptor(m_fd);//m_fd is the socket descriptor of another socket
//from another thread
Here's the the thread from which m_fd
is collected:
void TCPListenerThread::onNewConnection()
{
QTcpSocket *clientSocket = m_tcpServer->nextPendingConnection();
int sockfd = clientSocket->socketDescriptor();
m_connectThread = new TCPConnectThread(sockfd);
m_threadPool->start(m_connectThread);
}
Exception:
Most possible exception at 0x76edf9ea in manager_host.exe:
0xC0000008: An invalid handle was specified
How and where may I find this invalid handle ?
Upvotes: 3
Views: 814
Reputation: 29896
You can't use the socket descriptor of a QTcpSocket
object if it is already used by another QTcpSocket
object. There is also no method of de-assigning it once is assigned to a QTcpSocket
Even if you don't explicitly use the initial QTcpSocket
, if there is an event loop in the thread it was created (which is probably the case here), Qt will monitor it in that thread.
As an alternative, you could:
QTcpServer
class to redefine its incomingConnection(int socketDescriptor)
method to get that descriptor before it is assigned to a QTcpSocket
instead of using nextPendingConnection
ORpass directly the QTcpSocket
you receive from nextPendingConnection
instead of the socket descriptor as a parameter to the thread constructor, and move it to the other thread (see that note):
TCPConnectThread(QTcpSocket *socket)
: m_socket(socket)
{
m_socket−>setParent(0); // necessary to move the object to another thread
m_socket->moveToThread(this);
...
}
As the moving has to be done from the initial thread, the first alternative might be easier to do with a QRunnable
, because you might not have access easily to the future QThread
the runnable will be using.
Upvotes: 1