« Location de véhicule utilitaireUn train peut en cacher un autre »

Spécifications

20.06.12 | par Le Grincheux | Catégories: Mauvais esprit, Je hais l'informatique, Matheux pervers

Je n'ai pas une formation d'informaticien. Encore moins de développeur, mais je consacre une bonne partie de mon temps pas perdu pour tout le monde à écrire des outils de calcul scientifique. Quitte à passer du temps sur ce sujet, autant que ces outils soient portables.

J'ai donc une bible de chevet, les spécifications POSIX dans toutes leurs moutures et j'ai la prétention de commencer à les connaître.

Il faut avant tout signaler que ces spécifications sont assez floues pour que chacun puisse y aller de sa propre interprétation. Cela donne parfois des choses amusantes comme le problème de pthread_kill() dont j'ai déjà eu l'occasion de parler ici. Je viens en particulier de tomber sur quelque chose de réellement tordu dans les fonctions de réception de données sur des sockets. J'ai observé ce comportement bizarre sur recvfrom() sous Linux, mais je pense que toutes les fonctions recv() sont affectés de la même bizarrerie. D'aucuns me diront qu'il s'agit d'un comportement tout à fait normal mais j'ai comme d'affreux doutes. En tout cas, ce comportement normal n'est pas sain et il serait bon d'ajouter à l'interface des fonctions recv() un certain nombre de fonctions d'état.

En effet, la fonction recvfrom() considère, au moins sous Linux, que des données sont disponibles dès que le noyau a commencé à écrire quelque chose dans le tampon de réception et non à la fin de cette écriture qui n'est pas atomique. En d'autres termes, si une fonction a la mauvaise idée d'appeler recvfrom() lorsque le noyau est en train d'écrire dans ce tampon, le résultat de l'appel à la fonction recvfrom() n'est pas une trame complète. Elle est tronquée n'importe où lorsque l'ordonnanceur décide de donner la main à un autre fil d'exécution. Charge au développeur de trouver un artifice pour contourner le problème.

Des esprits forts vont me dire que c'est parfaitement voulu parce que la taille d'un message peut dépasser la taille du tampon. Certes, mais dans ce cas, c'est une erreur de conception du mécanisme de communication, au choix du noyau ou de l'application, et si le problème était réellement celui-ci, il faudrait au minimum avoir un paramètre supplémentaire pour que recvfrom() ne retourne une donnée que lorsque celle-ci est complète, plutôt que de bidouiller un truc abscons avec un poll() et un timeout pour savoir si par hasard il n'y aurait pas la fin de la trame en cours dans les tuyaux, ce salopard d'ordonnanceur ayant entre temps donné la main à un autre fil.

Il n'y a pas à dire. Dave Cutler avait raison en signalant que les mécanismes d'entrée-sortie des systèmes Unix sont du type « getta byte, getta byte, getta byte-byte-byte ! » (à chanter sur l'air de l'ouverture de Guillaume Tell de Rossini)… Parce qu'à tout vouloir sous forme de descripteur de fichiers, la limitation du mécanisme est la taille des tampons. Et la conséquence immédiate de cette limitation est la gestion sous-optimale, octet par octet (ou bloc de taille limitée par bloc) de ces opérations d'entrée-sortie mâtinées d'un système de décodage des débuts et fins de trame.

 

2 commentaires

Evaluations des utilisateurs
5 étoile:
 
(1)
4 étoile:
 
(0)
3 étoile:
 
(0)
2 étoile:
 
(0)
1 étoile:
 
(0)
1 note
Evaluation moyenne des utilisateurs:
5.0 stars
(5.0)
Commentaire de: tuxmips
tuxmips
5 stars

Bonsoir

:-)

Bon ben en attendant, ca n’empêche pas ma gnu-Mageia-Linux ou ma gnu-Linux Debian de fonctionner :-D

21.06.12 @ 21:42
Commentaire de: Le Grincheux

Certes, mais ça explique aussi les plantages aléatoires de mes serveurs Linux/Debian diskless qui utilisent un DISK$SYSTEM, pardon, une partition root en NFSv3/UDP.

21.06.12 @ 22:14


Formulaire en cours de chargement...