2012-05-23 10 views
5

Mi código usa boost :: asio y io_service en un solo subproceso para realizar varias operaciones de socket. Todas las operaciones son asincrónicas y cada controlador depende de boost::system::error_code (particularmente boost::asio::error::operation_aborted) para determinar el resultado de la operación.boost :: asio async handlers invocados sin error después de la cancelación

Ha funcionado perfectamente bien hasta que cambié la lógica para hacer varias conexiones simultáneas y escogí la más rápida. Es decir, cuando se activa el primer controlador async_read_some, cancelo otros sockets (apagado, cierre - todo) y procedo con el actual. En el 95% de los casos, los manejadores de lectura de otros sockets se invocan con el error operation_aborted. Sin embargo, a veces, estos manejadores de lectura se invocan sin errores, diciéndome que han recibido con éxito N bytes.

Pero la documentación para el zócalo :: cancel() states:

Esta función hace que asíncrono excepcionales conectar, enviar y recibir operaciones para terminar de inmediato, y se pasarán los manejadores para operaciones canceladas el boost::asio::error::operation_aborted error.

Entonces, las preguntas: ¿Realmente puedo confiar en el error operation_aborted en el código de producción? Si puedo, ¿es un error en Asio del impulso 1.46.1? Si no puedo, ¿hay alguna documentación oficial con respecto a esto?

+1

Parece que en su caso los controladores múltiples han "tenido éxito" antes de invocar la cancelación. Puede confiar en que 'operation_aborted' se pase a los controladores que aún no se hayan ejecutado (y que están esperando ser llamados). – Chad

Respuesta

11

bien, las respuestas:

  1. No, no puedo confiar en el error operation_aborted solamente.
  2. Por supuesto, no es un error en Asio, solo la falta de experiencia de mi parte.
  3. Hay un poco de documentation oficial. Es para temporizadores, ni tomas de corriente, sin embargo, se aplican los mismos principios:

Si el temporizador ya ha expirado cuando cancel() se llama, a continuación, los controladores para operaciones de espera asíncronos hará lo siguiente:

  • ya han sido invocados; o
  • se han puesto en cola para la invocación en el futuro cercano.

Básicamente, yo estaba equivocado en suposición de que si uso un solo hilo para io_service, entonces cada operación será bloqueada mientras que algunos controlador ejecuta.

El comportamiento que estoy informando en realidad tiene mucho sentido y parece que todos los que usan Asio lo saben.Revisé las listas de correo de Asio y encontré mucha discusión sobre el tema here, here, here y here.

Por ejemplo, una operación de escritura se complete con éxito, mientras que está dentro de un manejador, pero antes de haber encontrado el momento de llamar a toma cancelan, provocando su manejador de finalización para ser enviado a la cola. Según tengo entendido, el código de error está determinado por el estado de la operación que se completó, no el estado del socket en el momento en que el manejador se elimina de la cola y se ejecuta.

+1

+1 para la respuesta ordenada a su propia pregunta –

2

Considere la posibilidad de establecer dos conexiones al mismo tiempo. Ambos manejadores dispararán, uno será manejado primero, el segundo estará en la cola (o será manejado en un hilo diferente). Uno puede pensar en más ejemplos como ese.

Para implementar su requerimiento, necesita un poco más de lógica.