Implemento il server di giochi in cui ho bisogno di leggere e scrivere. Quindi accetto la connessione in entrata e inizio a leggerlo usando aio_read() ma quando ho bisogno di inviare qualcosa, smetto di leggere usando aio_cancel() e poi usare aio_write(). All'interno della callback di write riprendo a leggere. Quindi, leggo tutto il tempo ma quando ho bisogno di inviare qualcosa - I pausa lettura.C - Come utilizzare entrambi aio_read() e aio_write()
Si lavora per ~ 20% di tempo - in altri casi chiamata a aio_cancel() fallisce con "Operazione in corso" - e non posso cancellarlo (anche all'interno permanente ciclo mentre). Quindi, la mia operazione di scrittura aggiunta non accade mai.
Come utilizzare bene queste funzioni? Cosa mi sono perso?
MODIFICA: Utilizzato sotto Linux 2.6.35. Ubuntu 10 - 32 bit.
codice Esempio:
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(...);
}
}
È necessario specificare quale sistema operativo è. Prova anche a creare un esempio di auto-contenuto minimo che mostri il problema. Altrimenti, sei sicuro di doverlo cancellare? Penso che sia perfettamente ok avere entrambe le operazioni di lettura e scrittura in sospeso sullo stesso descrittore di file. –
In C++ uso due thread per operare sullo stesso socket allo stesso tempo. Un lettore, uno scrittore. Penso che questo potrebbe funzionare anche con aio, ma non sono sicuro, ma forse questo potrebbe rispondere a qualcuno. –
Puoi spiegare _perché_ hai bisogno di mettere in pausa la lettura? Non ti permette di inviare una richiesta di scrittura senza cancellare la lettura? –