--- rpl/src/semaphores.c 2011/09/18 18:06:01 1.30 +++ rpl/src/semaphores.c 2011/09/19 17:33:17 1.32 @@ -131,48 +131,64 @@ int sem_getvalue2(sem_t *semaphore, int *valeur) { int i; + int j; logical1 drapeau_fin; - // Si on ne peut pas décrémenter le sémaphore, c'est qu'il était - // déjà nul. - 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); } @@ -192,9 +208,9 @@ sem_getvalue2(sem_t *semaphore, int *val ================================================================================ */ -#ifndef OS2 - extern unsigned char *chemin_semaphores_SysV; -#else +#ifndef OS2 // IPCS_SYSV + extern unsigned char *racine_segment; +#else // OS/2 unsigned char racine_semaphores_OS2[] = "\\SEM32\\"; unsigned char racine_memoire_OS2[] = "\\SHAREMEM\\"; #endif @@ -204,35 +220,69 @@ sem_init_SysV(sem_t *semaphore, int shar { // Création d'un sémaphore anonyme qui devra être supprimé par // sem_destroy_SysV -# ifndef OS2 - int ios; +# ifndef OS2 // IPCS_SYSV + int desc; + int ios; + + key_t clef; + + union semun argument; + + if (shared == 0) + { + // Sémaphore privé + (*semaphore).sem = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | + S_IRUSR | S_IWUSR); + (*semaphore).path = NULL; + (*semaphore).pid = getpid(); + (*semaphore).alloue = 0; + } + else + { + // Sémaphore partagé entre plusieurs processus + if (((*semaphore).path = malloc((strlen(racine_segment) + + 1 + 32 + 1) * sizeof(unsigned char))) == NULL) + { + return(-1); + } - union semun argument; + sprintf((*semaphore).path, "%s/RPL-SIGSEMAPHORE-%d", racine_segment, + (int) getpid()); - if (shared != 0) - { - errno = ENOSYS; - return(-1); - } + if ((desc = open((*semaphore).path, O_CREAT | O_EXCL | + S_IRUSR | S_IWUSR)) == -1) + { + free((*semaphore).path); + return(-1); + } - (*semaphore).sem = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | - S_IRUSR | S_IWUSR); - (*semaphore).path = NULL; - (*semaphore).pid = getpid(); + (*semaphore).pid = getpid(); + clef = ftok((*semaphore).path, 1); + close(desc); - if ((*semaphore).sem == -1) - { - errno = EINVAL; - return(-1); - } + if (clef == -1) + { + free((*semaphore).path); + return(-1); + } - argument.val = valeur; - ios = semctl((*semaphore).sem, 0, SETVAL, argument); + (*semaphore).alloue = 0; + (*semaphore).sem = semget(clef, 1, IPC_CREAT | IPC_EXCL | + S_IRUSR | S_IWUSR); + } + + if ((*semaphore).sem == -1) + { + errno = EINVAL; + return(-1); + } - return(ios); + argument.val = valeur; + ios = semctl((*semaphore).sem, 0, SETVAL, argument); -# else + return(ios); +# else // OS/2 sem_t *psem; @@ -290,26 +340,25 @@ int sem_destroy_SysV(sem_t *semaphore) { // Détruit un sémaphore anonmyme -# ifndef OS2 - - if ((*semaphore).path != NULL) - { - return(EINVAL); - } - if ((*semaphore).pid != getpid()) - { - return(0); - } +# ifndef OS2 // IPCS_SYSV + if ((*semaphore).path != NULL) + { + return(EINVAL); + } - if (semctl((*semaphore).sem, 0, IPC_RMID) == -1) - { - return(EINVAL); - } + if ((*semaphore).pid != getpid()) + { + return(0); + } - return(0); + if (semctl((*semaphore).sem, 0, IPC_RMID) == -1) + { + return(EINVAL); + } -# else + return(0); +# else // OS/2 sem_t *psem; @@ -358,26 +407,24 @@ sem_destroy_SysV(sem_t *semaphore) int sem_wait_SysV(sem_t *semaphore) { -# ifndef OS2 - - struct sembuf commande; +# ifndef OS2 // IPCS_SYSV + struct sembuf commande; - commande.sem_num = 0; - commande.sem_op = -1; - commande.sem_flg = 0; + commande.sem_num = 0; + commande.sem_op = -1; + commande.sem_flg = 0; - while(semop((*semaphore).sem, &commande, 1) == -1) - { - if (errno != EINTR) + while(semop((*semaphore).sem, &commande, 1) == -1) { - errno = EINVAL; - return(-1); + if (errno != EINTR) + { + errno = EINVAL; + return(-1); + } } - } - - return(0); -# else + return(0); +# else // OS/2 sem_t *psem; @@ -416,26 +463,24 @@ sem_wait_SysV(sem_t *semaphore) int sem_trywait_SysV(sem_t *semaphore) { -# ifndef OS2 +# ifndef OS2 // IPCS_SYSV + struct sembuf commande; - struct sembuf commande; + commande.sem_num = 0; + commande.sem_op = -1; + commande.sem_flg = IPC_NOWAIT; - commande.sem_num = 0; - commande.sem_op = -1; - commande.sem_flg = IPC_NOWAIT; - - while(semop((*semaphore).sem, &commande, 1) == -1) - { - if (errno != EINTR) + while(semop((*semaphore).sem, &commande, 1) == -1) { - errno = EINVAL; - return(-1); + if (errno != EINTR) + { + errno = EINVAL; + return(-1); + } } - } - - return(0); -# else + return(0); +# else // OS/2 int ios; @@ -476,26 +521,24 @@ sem_trywait_SysV(sem_t *semaphore) int sem_post_SysV(sem_t *semaphore) { -# ifndef OS2 - - struct sembuf commande; +# ifndef OS2 // IPCS_SYSV + struct sembuf commande; - commande.sem_num = 0; - commande.sem_op = 1; - commande.sem_flg = 0; + commande.sem_num = 0; + commande.sem_op = 1; + commande.sem_flg = 0; - while(semop((*semaphore).sem, &commande, 1) == -1) - { - if (errno != EINTR) + while(semop((*semaphore).sem, &commande, 1) == -1) { - errno = EINVAL; - return(-1); + if (errno != EINTR) + { + errno = EINVAL; + return(-1); + } } - } - return(0); - -# else + return(0); +# else // OS/2 sem_t *psem; @@ -519,17 +562,15 @@ sem_post_SysV(sem_t *semaphore) int sem_getvalue_SysV(sem_t *semaphore, int *valeur) { -# ifndef OS2 - - (*valeur) = semctl((*semaphore).sem, 0, GETVAL); - - if ((*valeur) < 0) - { - return(EINVAL); - } +# ifndef OS2 // IPCS_SYSV + (*valeur) = semctl((*semaphore).sem, 0, GETVAL); - return(0); + if ((*valeur) < 0) + { + return(EINVAL); + } + return(0); # else sem_t *psem; @@ -560,11 +601,11 @@ sem_t sem_t *semaphore; # ifndef OS2 - file *desc; + int desc; - key_t clef; + key_t clef; - union semun argument; + union semun argument; # endif unsigned char *nom_absolu; @@ -574,29 +615,29 @@ sem_t va_list liste; # ifdef OS2 - sem_t *psem; + sem_t *psem; - PVOID base; + PVOID base; - unsigned char *ptr; - unsigned char *nom_segment; + unsigned char *ptr; + unsigned char *nom_segment; # endif -# ifndef OS2 - - if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom) - + 1) * sizeof(unsigned char))) == NULL) - { - return(SEM_FAILED); - } +# ifndef OS2 // IPCS_SYSV + if ((nom_absolu = malloc((strlen(racine_segment) + strlen(nom) + + 2) * sizeof(unsigned char))) == NULL) + { + return(SEM_FAILED); + } - sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom); + sprintf(nom_absolu, "%s/%s", racine_segment, nom); - if ((semaphore = malloc(sizeof(sem_t))) == NULL) - { - return(SEM_FAILED); - } + if ((semaphore = malloc(sizeof(sem_t))) == NULL) + { + return(SEM_FAILED); + } + (*semaphore).alloue = -1; # else if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1) @@ -652,29 +693,26 @@ sem_t { // 2 arguments -# ifndef OS2 - - clef = ftok(nom_absolu, 1); - - if (clef == -1) - { - return(SEM_FAILED); - } - - (*semaphore).sem = semget(clef, 0, 0); - (*semaphore).path = nom_absolu; - (*semaphore).pid = getpid(); - - if ((*semaphore).sem == -1) - { - free(semaphore); - free(nom_absolu); +# ifndef OS2 // IPCS_SYSV + clef = ftok(nom_absolu, 1); - return(SEM_FAILED); - } + if (clef == -1) + { + return(SEM_FAILED); + } -# else + (*semaphore).sem = semget(clef, 0, 0); + (*semaphore).path = nom_absolu; + (*semaphore).pid = getpid(); + + if ((*semaphore).sem == -1) + { + free(semaphore); + free(nom_absolu); + return(SEM_FAILED); + } +# else // OS/2 if ((psem = malloc(sizeof(sem_t))) == NULL) { free(nom_absolu); @@ -754,45 +792,45 @@ sem_t valeur = va_arg(liste, unsigned int); va_end(liste); -# ifndef OS2 - - if ((desc = fopen(nom_absolu, "w")) == NULL) - { - free(semaphore); - free(nom_absolu); - - return(SEM_FAILED); - } - - fclose(desc); +# ifndef OS2 // IPCS_SYSV + if ((desc = open(nom_absolu, O_CREAT | O_EXCL | S_IRUSR | S_IWUSR)) + == -1) + { + free(semaphore); + free(nom_absolu); - if ((clef = ftok(nom_absolu, 1)) == -1) - { - free(semaphore); - free(nom_absolu); + return(SEM_FAILED); + } - return(SEM_FAILED); - } + if ((clef = ftok(nom_absolu, 1)) == -1) + { + close(desc); + free(semaphore); + free(nom_absolu); - (*semaphore).sem = semget(clef, 1, - (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) | - (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) | - (int) mode); - (*semaphore).path = nom_absolu; - (*semaphore).pid = getpid(); + return(SEM_FAILED); + } - if ((*semaphore).sem == -1) - { - free(semaphore); - free(nom_absolu); + close(desc); - return(SEM_FAILED); - } + (*semaphore).sem = semget(clef, 1, + (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) | + (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) | + (int) mode); + (*semaphore).path = nom_absolu; + (*semaphore).pid = getpid(); + + if ((*semaphore).sem == -1) + { + free(semaphore); + free(nom_absolu); - argument.val = valeur; - semctl((*semaphore).sem, 0, SETVAL, argument); + return(SEM_FAILED); + } -# else + argument.val = valeur; + semctl((*semaphore).sem, 0, SETVAL, argument); +# else // OS/2 if ((psem = malloc(sizeof(sem_t))) == NULL) { @@ -858,16 +896,18 @@ int sem_close_SysV(sem_t *semaphore) { // Ferme un sémaphore nommé créé par sem_open_SysV() -# ifndef OS2 - - if ((*semaphore).path != NULL) - { - free((*semaphore).path); - } +# ifndef OS2 // IPCS_SYSV + if ((*semaphore).path != NULL) + { + free((*semaphore).path); + } - free(semaphore); - return(0); + if ((*semaphore).alloue == -1) + { + free(semaphore); + } + return(0); # else sem_t *psem; @@ -913,29 +953,26 @@ int sem_unlink_SysV(const char *nom) { // Détruit un sémaphore nommé créé par sem_open_SysV() -# ifndef OS2 +# ifndef OS2 // IPCS_SYSV + unsigned char *nom_absolu; - unsigned char *nom_absolu; + if ((nom_absolu = malloc((strlen(racine_segment) + strlen(nom) + + 2) * sizeof(unsigned char))) == NULL) + { + return(ENOMEM); + } - if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom) - + 1) * sizeof(unsigned char))) == NULL) - { - return(ENOMEM); - } + sprintf(nom_absolu, "%s/%s", racine_segment, nom); + semctl(semget(ftok(nom_absolu, 1), 0, 0), 0, IPC_RMID); - sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom); - semctl(semget(ftok(nom_absolu, 1), 0, 0), 0, IPC_RMID); + if (unlink(nom_absolu) == -1) + { + free(nom_absolu); + return(EACCES); + } - if (unlink(nom_absolu) == -1) - { free(nom_absolu); - return(EACCES); - } - - free(nom_absolu); - - return(0); - + return(0); # else return(0);