--- rpl/src/semaphores.c 2011/08/09 11:31:37 1.28 +++ rpl/src/semaphores.c 2011/09/18 18:45:31 1.31 @@ -24,6 +24,25 @@ #ifdef SEMAPHORES_NOMMES +// Les fonctions suivantes ne sont utilisées que dans le cas d'un +// système POSIX qui ne possède pas de sémaphores anonymes. MacOS X +// est dans ce cas. + +static unsigned char * +nom_segment_semaphore(pid_t pid) +{ + unsigned char *fichier; + + if ((fichier = malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL) + { + return(NULL); + } + + sprintf(fichier, "/RPL-SIGSEMAPHORE-%d", (int) pid); + return(fichier); +} + + /* ================================================================================ Fonctions d'émulation de sémaphores anonymes @@ -37,21 +56,71 @@ */ sem_t * -sem_init2(unsigned int valeur, enum t_semaphore semaphore) +sem_init2(unsigned int valeur, pid_t pid) { - snprintf(noms_semaphores[semaphore], LONGUEUR_NOM_SEMAPHORE, - "/RPL-SEM-%d-%llu-%d", (int) getpid(), - (unsigned long long) pthread_self(), - (int) semaphore); - return(sem_open(noms_semaphores[semaphore], O_CREAT, - (S_IRUSR | S_IWUSR), valeur)); + sem_t *semaphore; + + unsigned char *chemin; + unsigned int i; + + if ((chemin = nom_segment_semaphore(pid)) == NULL) + { + return(SEM_FAILED); + } + + semaphore = sem_open(chemin, O_CREAT, (S_IRUSR | S_IWUSR), valeur); + free(chemin); + + for(i = 0; i < valeur; i++) + { + if (sem_post(semaphore) != 0) + { + sem_close(semaphore); + return(SEM_FAILED); + } + } + + return(semaphore); } + +sem_t * +sem_open2(pid_t pid) +{ + unsigned char *chemin; + + sem_t *semaphore; + + if ((chemin = nom_segment_semaphore(pid)) == NULL) + { + return(1); + } + + semaphore = sem_open(chemin, O_RDWR); + free(chemin); + + return(semaphore); +} + + int -sem_destroy2(sem_t *semaphore_p, enum t_semaphore semaphore) +sem_destroy2(sem_t *semaphore, pid_t pid) { - sem_close(semaphore_p); - return(sem_unlink(noms_semaphores[semaphore])); + int erreur; + + unsigned char *chemin; + + sem_close(semaphore); + + if ((chemin = nom_segment_semaphore(pid)) == NULL) + { + return(1); + } + + erreur = sem_unlink(chemin); + free(chemin); + + return(erreur); } #undef sem_post @@ -62,46 +131,64 @@ int sem_getvalue2(sem_t *semaphore, int *valeur) { int i; + int j; logical1 drapeau_fin; - pthread_mutex_lock(&mutex_sem); + struct timespec attente; - (*valeur) = 0; - drapeau_fin = d_faux; + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; - do + for(j = 0; j < 100; j++) { - if (sem_trywait(semaphore) == -1) + if (pthread_mutex_trylock(&mutex_sem) == 0) { - if (errno == EAGAIN) + (*valeur) = 0; + drapeau_fin = d_faux; + + do { - // Le sémaphore avait une valeur nulle - drapeau_fin = d_vrai; - } - else + if (sem_trywait(semaphore) == -1) + { + if (errno == EAGAIN) + { + // Le sémaphore avait une valeur nulle + drapeau_fin = d_vrai; + } + else + { + // Autre erreur + pthread_mutex_unlock(&mutex_sem); + return(-1); + } + } + else + { + (*valeur)++; + } + } while(drapeau_fin == d_faux); + + for(i = 0; i < (*valeur); i++) { - // Autre erreur - pthread_mutex_unlock(&mutex_sem); - return(-1); + if (sem_post(semaphore) != 0) + { + pthread_mutex_unlock(&mutex_sem); + return(-1); + } } - } - else - { - (*valeur)++; - } - } while(drapeau_fin == d_faux); - for(i = 0; i < (*valeur); i++) - { - if (sem_post(semaphore) != 0) - { pthread_mutex_unlock(&mutex_sem); - return(-1); + return(0); } + + INCR_GRANULARITE(attente.tv_nsec); } - pthread_mutex_unlock(&mutex_sem); + // Le mutex n'a pas pu être verrouillé. On peut raisonnablement penser + // que le sémaphore est bloqué dans un sem_wait() protégé par ce mutex. + + (*valeur) = 0; return(0); }