int ConnectionReadHeader( int fd, cMessageHeader *header ) { int rv = ConnectionRead( fd, header, sizeof( cMessageHeader ) ); if ( rv ) return rv; if ( (header->m_flags & dMhEndianBit) != MarshalByteOrder() ) { header->m_id = bswap_32( header->m_id ); header->m_len = bswap_32( header->m_len ); } return 0; }
int ConnectionReadMsg( int fd, cMessageHeader *header, void **response, unsigned int timeout_ms ) { int rv; if ( timeout_ms ) { rv = ConnectionWait( fd, timeout_ms ); if ( rv ) return rv; } rv = ConnectionReadHeader( fd, header ); if ( rv ) return rv; if ( header->m_len ) { assert( header->m_len < 0xffff ); void *data = malloc( header->m_len ); if ( !data ) return ENOMEM; rv = ConnectionRead( fd, data, header->m_len ); if ( rv ) return rv; *response = data; } return 0; }
static bool _ReaderRun(ThreadData _reader) { Reader* reader = (Reader*)_reader; QueueItem* item = NewQueueItem(); Connection* connection = NULL; SelectionKey* key = NULL; int numConnectionsReady = 0; while(Dequeue(reader->queue, item, false)) { switch(QueueItemGetType(item)) { case AIO4C_QUEUE_ITEM_EXIT: FreeQueueItem(&item); return false; case AIO4C_QUEUE_ITEM_DATA: connection = (Connection*)QueueDataItemGet(item); connection->readKey = Register(reader->selector, AIO4C_OP_READ, connection->socket, (void*)connection); Log(AIO4C_LOG_LEVEL_DEBUG, "managing connection %s", connection->string); ConnectionManagedBy(connection, AIO4C_CONNECTION_OWNER_READER); reader->load++; break; case AIO4C_QUEUE_ITEM_EVENT: connection = (Connection*)QueueEventItemGetSource(item); if (QueueEventItemGetEvent(item) == AIO4C_CLOSE_EVENT) { if (connection->readKey != NULL) { Unregister(reader->selector, connection->readKey, true, NULL); connection->readKey = NULL; } Log(AIO4C_LOG_LEVEL_DEBUG, "close received for connection %s", connection->string); reader->load--; if (ConnectionNoMoreUsed(connection, AIO4C_CONNECTION_OWNER_READER)) { Log(AIO4C_LOG_LEVEL_DEBUG, "freeing connection %s", connection->string); FreeConnection(&connection); } } else if (QueueEventItemGetEvent(item) == AIO4C_PENDING_CLOSE_EVENT) { Log(AIO4C_LOG_LEVEL_DEBUG, "pending close received for connection %s", connection->string); } break; default: break; } } ProbeTimeStart(AIO4C_TIME_PROBE_IDLE); numConnectionsReady = Select(reader->selector); ProbeTimeEnd(AIO4C_TIME_PROBE_IDLE); if (numConnectionsReady > 0) { ProbeTimeStart(AIO4C_TIME_PROBE_NETWORK_READ); while (SelectionKeyReady(reader->selector, &key)) { if (SelectionKeyIsOperationSuccessful(key)) { connection = ConnectionRead(SelectionKeyGetAttachment(key)); } else { Log(AIO4C_LOG_LEVEL_WARN, "select operation unsuccessful for connection %s", ((Connection*)SelectionKeyGetAttachment(key))->string); } } ProbeTimeEnd(AIO4C_TIME_PROBE_NETWORK_READ); } FreeQueueItem(&item); return true; }