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;
}
}
}
}
}