void socketio_dowork()

in adapters/socketio_win32.c [621:729]


void socketio_dowork(CONCRETE_IO_HANDLE socket_io)
{
    if (socket_io != NULL)
    {
        SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
        if (socket_io_instance->io_state == IO_STATE_OPEN)
        {
            LIST_ITEM_HANDLE first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
            while (first_pending_io != NULL)
            {
                PENDING_SOCKET_IO* pending_socket_io = (PENDING_SOCKET_IO*)singlylinkedlist_item_get_value(first_pending_io);
                if (pending_socket_io == NULL)
                {
                    LogError("Failure: retrieving socket from list");
                    indicate_error(socket_io_instance);
                    break;
                }

                /* TODO: we need to do more than a cast here to be 100% clean
                The following bug was filed: [WarnL4] socketio_win32 does not account for already sent bytes and there is a truncation of size from size_t to int */
                int send_result = send(socket_io_instance->socket, (const char*)pending_socket_io->bytes, (int)pending_socket_io->size, 0);
                if ((size_t)send_result != pending_socket_io->size)
                {
                    int last_error = WSAGetLastError();
                    if (last_error != WSAEWOULDBLOCK)
                    {
                        free(pending_socket_io->bytes);
                        free(pending_socket_io);
                        pending_socket_io = NULL;
                        (void)singlylinkedlist_remove(socket_io_instance->pending_io_list, first_pending_io);
                    }
                    else
                    {
                        /* try again */
                    }
                }
                else
                {
                    if (pending_socket_io->on_send_complete != NULL)
                    {
                        pending_socket_io->on_send_complete(pending_socket_io->callback_context, IO_SEND_OK);
                    }

                    free(pending_socket_io->bytes);
                    free(pending_socket_io);
                    pending_socket_io = NULL;
                    if (singlylinkedlist_remove(socket_io_instance->pending_io_list, first_pending_io) != 0)
                    {
                        LogError("Failure: removing socket from list");
                        indicate_error(socket_io_instance);
                    }
                }

                first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
            }

            if (socket_io_instance->io_state == IO_STATE_OPEN)
            {
                int received = 0;
                do
                {
                    received = recv(socket_io_instance->socket, (char*)socket_io_instance->recv_bytes, XIO_RECEIVE_BUFFER_SIZE, 0);
                    if ((received > 0))
                    {
                        if (socket_io_instance->on_bytes_received != NULL)
                        {
                            /* Explicitly ignoring here the result of the callback */
                            (void)socket_io_instance->on_bytes_received(socket_io_instance->on_bytes_received_context, socket_io_instance->recv_bytes, received);
                        }
                    }
                    else if (received == 0)
                    {
                        indicate_error(socket_io_instance);
                    }
                    else
                    {
                        int last_error = WSAGetLastError();
                        if (last_error != WSAEWOULDBLOCK && last_error != ERROR_SUCCESS)
                        {
                            LogError("Socketio_Failure: Receiving data from endpoint: %d.", last_error);
                            indicate_error(socket_io_instance);
                        }
                    }
                } while (received > 0 && socket_io_instance->io_state == IO_STATE_OPEN);
            }
        }
        else
        {
            //Handle async socket_open operation within socket_dowork
            if (socket_io_instance->io_state == IO_STATE_OPENING)
            {
                if (lookup_address(socket_io_instance) != 0)
                {
                    LogError("lookup_address failed");
                    (void)closesocket(socket_io_instance->socket);
                    socket_io_instance->socket = INVALID_SOCKET;
                    socket_io_instance->io_state = IO_STATE_CLOSED;
                }
                else if (socket_io_instance->io_state == IO_STATE_OPEN && initiate_socket_connection(socket_io_instance) != 0)
                {
                    LogError("initialize_socket_connection failed");
                    (void)closesocket(socket_io_instance->socket);
                    socket_io_instance->socket = INVALID_SOCKET;
                    socket_io_instance->io_state = IO_STATE_CLOSED;
                }
            }
        }
    }
}