Siempre deje la decisión de cómo manejar EINTR
al usuario y facilite la reanudación de la operación según corresponda.
Por lo general, la mejor manera de hacerlo es regresar de la función de la biblioteca a la persona que llama EINTR
, pero en algunos casos una devolución de llamada u otra implementación podría ser mejor; la mejor manera depende de otros factores, pero siempre permita que el usuario vuelva a intentar currículum.
Esto significa que si el código de su biblioteca puede tener éxito parcialmente antes de obtener un EINTR
, entonces debe pensar cuidadosamente lo que el usuario podría necesitar saber sobre ese éxito parcial, o si el usuario podría necesitar reanudar la operación desde donde falló. Es posible que deba devolver información adicional o proporcionar una interfaz para reanudar desde cualquier lugar donde sea apropiado.
Esta es la razón por la cual el sistema llama como read
y write
hoy en día devuelve un éxito parcial, porque es muy frustrante para el usuario que le digan:
Intentaste escribir "foo"
y nosotros escribimos con éxito nada, o "f"
, o "fo"
, y no sabes cuál . ¡Que te diviertas! ¡Espero que su sistema pueda manejar el reinicio de toda la escritura después de cualquiera de esos!
Por supuesto, en algunos casos, deberíamos escribir sistemas para manejar situaciones exactamente así, por ejemplo, tal vez después de una escritura parcial siempre recrea el archivo, o vuelve a abrir la conexión de red, o usa algún byte para significar "comenzar de nuevo" - por lo tanto, depende de los casos de uso a los que se dirija su biblioteca.
Si una función de biblioteca realiza varias operaciones, y no hay forma de saber en cuál de ellas falló, y esas operaciones no son idempotentes de manera segura y eficiente, eso básicamente hace que una biblioteca sea inutilizable para el código que necesita ser robusto.
Si todos los pasos en una función de biblioteca son idempotentes de manera segura y eficiente, o si todo es atómico, como adquirir un bloqueo, simplemente dejar que el usuario sepa que EINTR
sucedió es suficiente.
Además, si volvemos a intentarlo EINTR
, podríamos interrumpir el manejo de la señal . En el nivel bajo, los manejadores de señales solo pueden usar de manera segura un conjunto limitado de características, por lo que en muchos casos un manejador de señales solo establecerá un valor booleano que indica que se recibió la señal y luego regresará, esperando que cuando se reanude el código, lo haga. salir de lo que sea que estuviera haciendo. Si obtenemos un EINTR
mensaje y luego volvemos a intentarlo en lugar de devolverle el control al usuario, es posible que evitemos que el código lo haga.
Lo que se debe hacer después de una decisión deEINTR
un programa completo : no se puede saber la respuesta correcta sin saber qué está haciendo el programa y cómo debe responder a una señal, y tiene efectos en el resto del programa.
Saber cómo o si el usuario podría necesitar reanudar, y ayudarlo a hacerlo si es necesario, es una responsabilidad de la biblioteca: no se puede conocer la respuesta correcta sin saber lo que está haciendo la biblioteca.
EINTR
e informarlo a la persona que llama), pero puede depender de lo que esté haciendo su biblioteca ...