2010-11-18 6 views
9

J'ai examiné la mise en œuvre de points d'annulation par glibc/nptl et la comparaison avec POSIX, et à moins que je me trompe, c'est complètement faux. Le modèle de base utilisée est la suivante:Comment les points d'annulation POSIX sont-ils censés se comporter?

int oldtype = LIBC_ASYNC_CANCEL(); /* switch to asynchronous cancellation mode */ 
int result = INLINE_SYSCALL(...); 
LIBC_CANCEL_RESET(oldtype); 

Selon POSIX:

Les effets secondaires d'agir sur une demande d'annulation pendant la suspension lors d'un appel d'une fonction sont les mêmes que les effets secondaires que peut être vu dans un programme monothread lorsqu'un appel à une fonction est interrompu par un signal et la fonction donnée renvoie [EINTR]. Tous ces effets secondaires se produisent avant que les gestionnaires de nettoyage d'annulation sont appelés.

Ma lecture de ce passage est que si je l'appelle open, je peux attendre soit à être annulé (avec mon filet entier) avant qu'il ne parvient pas à ouvrir un fichier, ou retourner valide le descripteur de fichier ou la valeur -1 et errno, mais ne jamais créer un nouveau descripteur de fichier, puis le perdre dans le vide. D'un autre côté, l'implémentation de glibc/nptl des points d'annulation semble permettre une condition de concurrence dans laquelle la demande d'annulation se produit juste après le retour du syscall mais avant que LIBC_CANCEL_RESET ait lieu. Est-ce que je suis fou, ou est-ce que leur mise en œuvre est vraiment si cassée? Et si c'est le cas, est-ce que POSIX autorise un tel comportement brisé (qui semble rendre l'annulation complètement inutilisable à moins que vous ne le remettiez manuellement), ou ignore-t-il de façon flagrante POSIX?

Si ce comportement est en fait rompu, quelle est la bonne façon de l'implémenter sans une telle condition de concurrence?

Répondre

4

est-il pas précisé dans le paragraphe suivant de la norme:

Cependant, si le fil est suspendu à un point d'annulation et l'événement pour dont il attend se produit avant que la demande d'annulation est pris en compte, il est non spécifié si la demande d'annulation est traitée ou si la demande d'annulation reste en attente et le thread reprend exécution normale.

Ce qui implique que cette condition de concurrence est un comportement parfaitement légal.

+3

Comment écrire un programme robuste avec un tel comportement absurde? Il semble que vous deviez envelopper chaque appel de 'open' (et d'autres points d'annulation pouvant allouer des ressources) avec du code pour désactiver l'annulation, garder l'annulation toujours désactivée et appeler manuellement' pthread_trycancel' périodiquement, ou trouver un moyen de rechercher et libérer de telles ressources (pour les descripteurs de fichiers, il est possible de parcourir toutes les valeurs, mais il est assez dangereux de le faire dans une application threadée sans verrous lourds). –

+1

mmh, j'ai lu que comme le thread ne peut pas être annulé pour le moment, et devrait être annulé au prochain point d'annulation (Dans ce cas, les points d'annulation ont besoin de support OS, et sont probablement cassés de la manière que R .. la plupart des systèmes d'exploitation). – ninjalj

+0

@ninjaj: Je pense que cmeerw peut être correct. Le passage dit que si (par exemple) le thread est suspendu en attente de 'open' pour retourner, mais' open' a déjà fini de faire son travail, l'implémentation pourrait permettre l'annulation ou la laisser en attente. –

Questions connexes