• [^] # Re: Record battu

    Posté par . En réponse à la dépêche Libevent 2.0.1 alpha, la nouvelle version de libevent. Évalué à 3.

    select/poll/epoll/kqueue et compagnie permettent de savoir si un file descriptor (c'est à dire socket, fichier, entrée standard, etc [1]) est lisible où écrivable. De base aucun de ces appels systèmes n'appel de callbacks, c'est le boulot de libevent de retrouver quelles fonctions appeler.

    Une des grandes nouvauté de la version 2.0 c'est le support du edge-triggering : l'ancien mécanisme (level-triggering) notifie l'utilisateur quand des données sont en attente dans les buffers du noyau, c'est à dire que tant qu'il y a des données à lire on est notifié.

    L'edge-triggering par contre ne notifie pas l'utilisateur quand une socket est lisible/écrivable mais quand elle _devient_ lisible/ecrivable, c'est à dire que tant qu'on a pas entièrement vidé ou rempli les buffer du noyau on ne recoit plus d'événements (avec des IO non bloquants, on sait qu'on a vidé/rempli le buffer du noyau quand read/write échouent avec errno == EAGAIN).

    L'avantage du edge-triggering c'est qu'il y a beaucoup moins d'appels systèmes à faire, notamment pour l'écriture. Avec le level triggering il fallait, à chaque fois qu'on a un truc à écrire, demander à epoll/kqueue si la socket est écrivable (donc un appel système pour ajouter la demande d'écriture, un appel système pour attendre la réponse du noyau, et enfin un appel système pour retirer la demande d'écriture).

    Là on se contente d'ajouter la demande d'écriture au début, et tant que write ne renvoit pas d'erreur, on écris directement, sinon on attend que la socket redeviennent écrivable.

    La version 2.0 est vraiment alléchante, la zero-copy est très importante aussi, en gros éviter au maximum les copies de buffers. sendfile() permet par exemple d'écrire directement un fichier dans une socket sans passer par un buffer temporaire dans le programme. vmsplice() à aussi une option très intéressante qui permet de carrément 'donner' une page mémoire au kernel pour qu'il l'écrive dans une socket plutôt que de la recopier.

    C'est du bon, la version stable de libevent m'avait un peu décu par rapport à la plus récente libev [2] (trop grosse, des bugs un peu bête sur epoll, etc), mais je teste la version 2.0 dès que possible :)

    [1]: À noter que epoll ne gêre pas les fichiers réguliers, ceux-ci sont censé pouvoir être lu et écrit sans bloquer.
    [2]: http://software.schmorp.de/pkg/libev.html