Outre les vérifications de valeur de retour manquantes, il existe d'autres problèmes qui devraient être résolus :
sem_destroy
n'est pas appelé.- Signal/diffusion touchez le
cond_node_t
après avoir réveillé le thread cible, ce qui peut entraîner un use-after-free.
Autres commentaires :
- L'opération de destruction omise peut nécessiter des modifications des autres opérations, il est donc sûr de détruire la variable de condition lorsque POSIX dit qu'elle doit être sûre. Ne pas prendre en charge la destruction ou imposer des restrictions plus strictes sur le moment où il peut être appelé simplifiera les choses.
- Une implémentation de production gérerait l'annulation de threads.
- Annulation d'une attente (comme requis pour l'annulation de thread et
pthread_cond_timedwait
délais d'attente) peut entraîner des complications. - Votre implémentation met les threads en file d'attente dans userland, ce qui est fait dans certaines implémentations de production pour des raisons de performances ; Je ne comprends pas exactement pourquoi.
- Votre implémentation met toujours les threads en file d'attente dans l'ordre LIFO. Ceci est souvent plus rapide (par exemple à cause des effets de cache) mais peut conduire à la famine. La mise en œuvre de la production peut parfois utiliser l'ordre FIFO pour éviter la famine.
Fondamentalement, votre stratégie semble correcte, mais vous avez un danger majeur, un comportement indéfini et une pioche :
- vous n'inspectez pas les valeurs de retour de vos fonctions POSIX. En particulier
sem_wait
est interruptible, donc en cas de charge importante ou de malchance, votre fil sera réveillé de manière intempestive. Il faudrait bien attraper tout ça - aucune de vos fonctions ne renvoie de valeur. Si un utilisateur des fonctions décide un jour d'utiliser les valeurs de retour, il s'agit d'un comportement indéfini. Analysez soigneusement les codes d'erreur que les fonctions de condition sont autorisées à renvoyer et faites exactement cela.
- ne transmettez pas le retour de
malloc
oucalloc
Modifier : En fait, vous n'avez pas besoin de malloc
/free
du tout. Une variable locale ferait également l'affaire.