#include "loquet.h" /* Initialisation d'un loquet (partageable seulement entre les threads d'un meme processus) a l'adresse pointee par loquet. L'argument value specifie la valeur initiale du loquet. Parametre loquet : Pointeur vers la zone memoire contenant toutes les donnees liees au loquet a initialiser Parametre value : Valeur initiale du loquet Valeur de retour : nouveauLoquet renvoie 0 en cas de succes; en cas d'erreur, -1 est retourne et errno est positionne pour indiquer l'erreur. */ int nouveauLoquet( loquet_t *loquet , u_int value ){ int rc; loquet->compteur = value; loquet->nbAttenteLoquetOuvert = 0; pthread_mutex_init(&loquet->mutex, NULL); rc = sem_init(&loquet->attenteLoquetOuvert,0,0); return rc; } /* Decremente le compteur associe a loquet pour indiquer qu'un evenement est survenu. Parametre loquet : Pointeur vers la zone memoire contenant toutes les donnees liees au loquet concerne Valeur de retour : nouveauLoquet renvoie 0 en cas de succes; en cas d'erreur, -1 est retourne et errno est positionne pour indiquer l'erreur. */ int decrementLoquet( loquet_t *loquet ){ int rc; rc = pthread_mutex_lock(&loquet->mutex); if (rc != 0) { return -1; } loquet->compteur -= 1; if (loquet->compteur == 0) { int i; for (i = 0; i < loquet->nbAttenteLoquetOuvert; i++) { rc = sem_post(&loquet->attenteLoquetOuvert); if (rc != 0) { return -1; } } } rc = pthread_mutex_unlock(&loquet->mutex); if (rc != 0) { return -1; } return 0; } /* Attend que le compteur associe a loquet passe à zero (ce qui signifie que tous les evenements se sont passes). Si le compteur est non nul lorsqu'elle est appelee, la fonction attenteLoquet() se bloque jusqu'a ce que le compteur atteigne zero. Si le compteur est nul, attenteLoquet() retourne immediatement. Parametre loquet : Pointeur vers la zone memoire contenant toutes les donnees liees au loquet concerne Valeur de retour : nouveauLoquet renvoie 0 en cas de succes; en cas d'erreur, -1 est retourne et errno est positionne pour indiquer l'erreur. */ int attenteLoquet( loquet_t *loquet ){ int rc; rc = pthread_mutex_lock(&loquet->mutex); if (rc != 0) { return -1; } if (loquet->compteur > 0) { loquet->nbAttenteLoquetOuvert += 1; rc = pthread_mutex_unlock(&loquet->mutex); if (rc != 0) { return -1; } rc = sem_wait(&loquet->attenteLoquetOuvert); if (rc != 0) { return -1; } } else { rc = pthread_mutex_unlock(&loquet->mutex); if (rc != 0) { return -1; } } return 0; } /* Detruit le loquet a l'adresse pointee par loquet. Parametre loquet : Pointeur vers la zone memoire contenant toutes les donnees liees au loquet concerne Valeur de retour : nouveauLoquet renvoie 0 en cas de succes; en cas d'erreur, -1 est retourne et errno est positionne pour indiquer l'erreur. */ int destructionLoquet( loquet_t *loquet ){ return sem_destroy(&loquet->attenteLoquetOuvert); }