Implemento un servidor de juegos donde necesito leer y escribir. Así que acepto la conexión entrante y empiezo a leer usando aio_read() pero cuando necesito enviar algo, dejo de leer usando aio_cancel() y luego uso aio_write(). Dentro de la devolución de llamada de escritura, reanudo la lectura. Por lo tanto, leo todo el tiempo pero cuando necesito enviar algo - I pausa lectura.C - Cómo usar aio_read() y aio_write()
Funciona para ~ 20% del tiempo - en el caso de otra llamada a aio_cancel() falla con la "Operación ahora en progreso" - y no puedo cancelarlo (incluso dentro del ciclo permanente mientras ). Entonces, mi operación de escritura agregada nunca ocurre.
¿Cómo utilizar bien estas funciones? ¿Qué extrañé?
EDIT: Utilizado en Linux 2.6.35. Ubuntu 10 - 32 bit.
código Ejemplo:
void handle_read(union sigval sigev_value) { /* handle data or disconnection */ }
void handle_write(union sigval sigev_value) { /* free writing buffer memory */ }
void start()
{
const int acceptorSocket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
bind(acceptorSocket, (struct sockaddr*)&addr, sizeof(struct sockaddr_in));
listen(acceptorSocket, SOMAXCONN);
struct sockaddr_in address;
socklen_t addressLen = sizeof(struct sockaddr_in);
for(;;)
{
const int incomingSocket = accept(acceptorSocket, (struct sockaddr*)&address, &addressLen);
if(incomingSocket == -1)
{ /* handle error ... */}
else
{
//say socket to append outcoming messages at writing:
const int currentFlags = fcntl(incomingSocket, F_GETFL, 0);
if(currentFlags < 0) { /* handle error ... */ }
if(fcntl(incomingSocket, F_SETFL, currentFlags | O_APPEND) == -1) { /* handle another error ... */ }
//start reading:
struct aiocb* readingAiocb = new struct aiocb;
memset(readingAiocb, 0, sizeof(struct aiocb));
readingAiocb->aio_nbytes = MY_SOME_BUFFER_SIZE;
readingAiocb->aio_fildes = socketDesc;
readingAiocb->aio_buf = mySomeReadBuffer;
readingAiocb->aio_sigevent.sigev_notify = SIGEV_THREAD;
readingAiocb->aio_sigevent.sigev_value.sival_ptr = (void*)mySomeData;
readingAiocb->aio_sigevent.sigev_notify_function = handle_read;
if(aio_read(readingAiocb) != 0) { /* handle error ... */ }
}
}
}
//called at any time from server side:
send(void* data, const size_t dataLength)
{
//... some thread-safety precautions not needed here ...
const int cancellingResult = aio_cancel(socketDesc, readingAiocb);
if(cancellingResult != AIO_CANCELED)
{
//this one happens ~80% of the time - embracing previous call to permanent while cycle does not help:
if(cancellingResult == AIO_NOTCANCELED)
{
puts(strerror(aio_return(readingAiocb))); // "Operation now in progress"
/* don't know what to do... */
}
}
//otherwise it's okay to send:
else
{
aio_write(...);
}
}
Debe especificar qué sistema operativo es este. También intente crear un ejemplo autónomo mínimo que muestre el problema. De lo contrario, ¿estás seguro de que necesitas cancelarlo? Creo que está perfectamente bien tener pendientes las operaciones de lectura y escritura en el mismo descriptor de archivo. –
En C++ utilizo dos hilos para operar en el mismo socket al mismo tiempo. Un lector, un escritor Creo que esto podría funcionar también con aio, pero no estoy seguro, pero tal vez esto podría responder a alguien. –
¿Podría explicar por qué necesita detener la lectura? ¿Aio no le permite emitir una solicitud de escritura sin cancelar la lectura? –