bool GdbSrvRspClient::GetRspSessionStatus()

in Exdi/exdigdbsrv/GdbSrvControllerLib/GdbSrvRspClient.cpp [926:1016]


bool GdbSrvRspClient<TcpConnectorStream>::GetRspSessionStatus(_Out_ HRESULT & error, _In_ unsigned core)
{
    assert(m_pConnector != nullptr);
    bool isDone = false;

    bool isAllCores = (core == C_ALLCORES) ? true : false;
    size_t totalNumberOfProcessorCores = m_pConnector->GetNumberOfConnections();
    for (size_t coreNumber = 0; coreNumber < totalNumberOfProcessorCores; ++coreNumber)
    {
        if (isAllCores || coreNumber == core)
        {
            TcpIpStream * pStream = m_pConnector->GetLinkLayerStreamEntry(coreNumber);
            assert(pStream != nullptr);

            if (m_pConnector->IsConnected())
            {
                fd_set fdSetRead;
                fd_set fdSetError;
                struct timeval selectTimeout;
                selectTimeout.tv_sec = 0;
                selectTimeout.tv_usec = 500;       

                int numberOfSockets = pStream->Select(&fdSetRead, nullptr, &fdSetError, &selectTimeout);
                if (numberOfSockets != SOCKET_ERROR && numberOfSockets != 0)
                {
                    if (pStream->IsFDSet(&fdSetRead) != 0)
                    {
                        //  Ensure that the connection has been closed/terminated by trying to see
                        //  if this is not a close/reset/terminate false positive event, so we will try peeking the data
                        //  If there is a pending data then this is not caused by a close/terminating event.
                        //  Change the socket mode to non-blocking.
                        u_long mode = 1;
                        int modeStatus = pStream->Ioctlsocket(FIONBIO, &mode);
                        if (modeStatus != SOCKET_ERROR)
                        {
                            //  Look for any pending data
                            char tempBuffer[1];
                            if (pStream->Peek(tempBuffer, sizeof(tempBuffer), MSG_PEEK) != NO_ERROR)
                            {
                                //  We got an error, so find out if this is a lost socket connection type of error.
                                int peekerror = m_pConnector->GetLastError();
                                if (m_pConnector->IsConnectionLost(peekerror))
                                {
                                    //  We lost connection, so abort the GDB RSP session.
                                    error = ERROR_OPERATION_ABORTED;
                                }
                            }
                            if (error != ERROR_OPERATION_ABORTED)
                            {
                                //  Change back to blocking mode
                                mode = 0;
                                if (pStream->Ioctlsocket(FIONBIO, &mode) == SOCKET_ERROR)
                                {
                                    // This should be a fatal error as we cannot set back the previous socket mode.
                                    error = ERROR_OPERATION_ABORTED;
                                }
                            }
                        }
                        else
                        {
                            error = HRESULT_FROM_WIN32(m_pConnector->GetLastError());    
                        }
                    }
                    //  Is there a socket error?
                    else if (pStream->IsFDSet(&fdSetError) != 0)
                    {
                        DWORD socketError = 0;
                        DWORD socketErrorLength = sizeof(socketError);
                        int errorStatus = pStream->GetOptions(SOL_SOCKET, SO_ERROR, 
                                                              reinterpret_cast<char *>(&socketError),
                                                              reinterpret_cast<int *>(&socketErrorLength));
                        if (errorStatus != SOCKET_ERROR)
                        {
                            error = HRESULT_FROM_WIN32(socketError);
                        }
                        else
                        {
                            error = HRESULT_FROM_WIN32(m_pConnector->GetLastError());    
                        }
                    }
                }
                else
                {
                    error = HRESULT_FROM_WIN32(m_pConnector->GetLastError());    
                }
                isDone = true;
            }
        }
    }
    return isDone;
}