--- rpl/src/semaphores.c 2012/05/21 17:25:46 1.45 +++ rpl/src/semaphores.c 2020/01/10 11:15:51 1.89 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.9 - Copyright (C) 1989-2012 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.32 + Copyright (C) 1989-2020 Dr. BERTRAND Joël This file is part of RPL/2. @@ -23,8 +23,6 @@ #include "rpl-conv.h" -#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. @@ -34,12 +32,12 @@ nom_segment_semaphore(pid_t pid, int ord { unsigned char *fichier; - if ((fichier = malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL) + if ((fichier = sys_malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL) { return(NULL); } - sprintf(fichier, "/RPL-%d-%d", (int) pid, ordre); + sprintf(fichier, "/RPL-%llu-%d", (unsigned long long) pid, ordre); return(fichier); } @@ -49,12 +47,12 @@ nom_segment_semaphore_thread(pid_t pid, { unsigned char *fichier; - if ((fichier = malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL) + if ((fichier = sys_malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL) { return(NULL); } - sprintf(fichier, "/RPL-%d-%llX-%d", (int) pid, + sprintf(fichier, "/RPL-%llu-%llu-%d", (unsigned long long) pid, (unsigned long long) tid, ordre); return(fichier); } @@ -78,15 +76,47 @@ sem_init2(unsigned int valeur, pid_t pid sem_t *semaphore; unsigned char *chemin; + unsigned char *langue; if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL) { return(SEM_FAILED); } - semaphore = sem_open(chemin, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, - valeur); - free(chemin); + if ((semaphore = sem_open(chemin, O_RDWR | O_CREAT | O_EXCL, + S_IRUSR | S_IWUSR, valeur)) == SEM_FAILED) + { + if (errno == EEXIST) + { + if ((langue = getenv("LANG")) != NULL) + { + if (strncmp(langue, "fr", 2) == 0) + { + uprintf("+++Attention : Le sémaphore %s préexiste !\n", + chemin); + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", chemin); + } + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", chemin); + } + + if (sem_unlink(chemin) != 0) + { + sys_free(chemin); + return(SEM_FAILED); + } + + semaphore = sem_open(chemin, O_RDWR | O_CREAT | O_EXCL, + S_IRUSR | S_IWUSR, valeur); + } + } + + sys_free(chemin); return(semaphore); } @@ -98,15 +128,41 @@ sem_init3(unsigned int valeur, pid_t pid sem_t *semaphore; unsigned char *chemin; + unsigned char *langue; if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL) { return(SEM_FAILED); } - semaphore = sem_open(chemin, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR, - valeur); - free(chemin); + if ((semaphore = sem_open(chemin, O_RDWR | O_CREAT | O_EXCL, + S_IRUSR | S_IWUSR, valeur)) == SEM_FAILED) + { + if (errno == EEXIST) + { + if ((langue = getenv("LANG")) != NULL) + { + if (strncmp(langue, "fr", 2) == 0) + { + uprintf("+++Attention : Le sémaphore %s préexiste !\n", + chemin); + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", chemin); + } + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", chemin); + } + + semaphore = sem_open(chemin, O_RDWR | O_CREAT, + S_IRUSR | S_IWUSR, valeur); + } + } + + sys_free(chemin); return(semaphore); } @@ -125,7 +181,7 @@ sem_open2(pid_t pid, int ordre) } semaphore = sem_open(chemin, O_RDWR); - free(chemin); + sys_free(chemin); return(semaphore); } @@ -146,7 +202,7 @@ sem_destroy2(sem_t *semaphore, pid_t pid } erreur = sem_unlink(chemin); - free(chemin); + sys_free(chemin); return(erreur); } @@ -167,16 +223,12 @@ sem_destroy3(sem_t *semaphore, pid_t pid } erreur = sem_unlink(chemin); - free(chemin); + sys_free(chemin); return(erreur); } -#undef sem_post -#undef sem_wait -#undef sem_trywait - int sem_getvalue2(sem_t *semaphore, int *valeur) { @@ -232,6 +284,7 @@ sem_getvalue2(sem_t *semaphore, int *val return(0); } + nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } @@ -242,7 +295,11 @@ sem_getvalue2(sem_t *semaphore, int *val return(0); } -#endif + +#undef sem_post +#undef sem_wait +#undef sem_trywait + #ifdef IPCS_SYSV @@ -279,6 +336,8 @@ sem_init_SysV(sem_t *semaphore, int shar union semun argument; + unsigned char *langue; + if (shared == 0) { // Sémaphore privé @@ -292,20 +351,51 @@ sem_init_SysV(sem_t *semaphore, int shar else { // Sémaphore partagé entre plusieurs processus - if (((*semaphore).path = malloc((strlen(racine_segment) + if (((*semaphore).path = sys_malloc((strlen(racine_segment) + 2 + 256 + 1) * sizeof(unsigned char))) == NULL) { return(-1); } - sprintf((*semaphore).path, "%s/RPL-SEMAPHORE-%d-%llX-%d", - racine_segment, (int) getpid(), pthread_self(), shared); + sprintf((*semaphore).path, "%s/RPL-SEMAPHORE-%d-%llX-%llX", + racine_segment, (int) getpid(), + (long long unsigned) pthread_self(), + (long long unsigned) semaphore); if ((desc = open((*semaphore).path, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) == -1) { - free((*semaphore).path); - return(-1); + if (errno != EEXIST) + { + sys_free((*semaphore).path); + return(-1); + } + + if ((langue = getenv("LANG")) != NULL) + { + if (strncmp(langue, "fr", 2) == 0) + { + uprintf("+++Attention : Le sémaphore %s préexiste !\n", + (*semaphore).path); + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", + (*semaphore).path); + } + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", + (*semaphore).path); + } + + if ((desc = open((*semaphore).path, O_RDWR | O_CREAT, + S_IRUSR | S_IWUSR)) == -1) + { + sys_free((*semaphore).path); + return(-1); + } } (*semaphore).pid = getpid(); @@ -315,7 +405,7 @@ sem_init_SysV(sem_t *semaphore, int shar if (clef == -1) { - free((*semaphore).path); + sys_free((*semaphore).path); return(-1); } @@ -330,7 +420,7 @@ sem_init_SysV(sem_t *semaphore, int shar return(-1); } - argument.val = valeur; + argument.val = (int) valeur; ios = semctl((*semaphore).sem, 0, SETVAL, argument); return(ios); @@ -339,26 +429,26 @@ sem_init_SysV(sem_t *semaphore, int shar psem = semaphore; - if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL) + if (((*psem).cnt = sys_malloc(sizeof(ULONG))) == NULL) { - free(psem); + sys_free(psem); errno = ENOMEM; return(-1); } - if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL) + if (((*psem).nopened = sys_malloc(sizeof(ULONG))) == NULL) { - free((*psem).cnt); - free(psem); + sys_free((*psem).cnt); + sys_free(psem); errno = ENOMEM; return(-1); } if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0) { - free((*psem).cnt); - free((*psem).nopened); - free(psem); + sys_free((*psem).cnt); + sys_free((*psem).nopened); + sys_free(psem); return(-1); } @@ -366,9 +456,9 @@ sem_init_SysV(sem_t *semaphore, int shar != 0) { DosCloseMutexSem((*psem).hmtx); - free((*psem).cnt); - free((*psem).nopened); - free(psem); + sys_free((*psem).cnt); + sys_free((*psem).nopened); + sys_free(psem); return(-1); } @@ -427,8 +517,8 @@ sem_destroy_SysV(sem_t *semaphore) if ((*psem).shared == 0) { - free((*psem).cnt); - free((*psem).nopened); + sys_free((*psem).cnt); + sys_free((*psem).nopened); } else { @@ -440,7 +530,7 @@ sem_destroy_SysV(sem_t *semaphore) if ((*psem).allocated != 0) { - free(psem); + sys_free(psem); } return(0); @@ -453,17 +543,23 @@ sem_wait_SysV(sem_t *semaphore) # ifndef OS2 // IPCS_SYSV struct sembuf commande; + // semop() ne renvoie pas EINTR sur un signal ! + commande.sem_num = 0; commande.sem_op = -1; commande.sem_flg = 0; - while(semop((*semaphore).sem, &commande, 1) == -1) + if (semop((*semaphore).sem, &commande, 1) == -1) { - if (errno != EINTR) + if (errno != EAGAIN) { errno = EINVAL; return(-1); } + else + { + return(-1); + } } return(0); @@ -511,13 +607,9 @@ sem_trywait_SysV(sem_t *semaphore) commande.sem_op = -1; commande.sem_flg = IPC_NOWAIT; - while(semop((*semaphore).sem, &commande, 1) == -1) + if (semop((*semaphore).sem, &commande, 1) == -1) { - if (errno != EINTR) - { - errno = EINVAL; - return(-1); - } + return(-1); } return(0); @@ -557,6 +649,64 @@ sem_trywait_SysV(sem_t *semaphore) # endif } +#ifndef timespeccmp +# define timespeccmp(tsp, usp, cmp) \ + (((tsp)->tv_sec == (usp)->tv_sec) ? \ + ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \ + ((tsp)->tv_sec cmp (usp)->tv_sec)) +# define timespecadd(tsp, usp, vsp) \ + do { \ + (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \ + (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \ + if ((vsp)->tv_nsec >= 1000000000L) { \ + (vsp)->tv_sec++; \ + (vsp)->tv_nsec -= 1000000000L; \ + } \ + } while(0) +# define timespecsub(tsp, usp, vsp) \ + do { \ + (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \ + (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \ + if ((vsp)->tv_nsec < 0) { \ + (vsp)->tv_sec--; \ + (vsp)->tv_nsec += 1000000000L; \ + } \ + } while(0) +#endif + +int +sem_timedwait_SysV(sem_t *sem, struct timespec *ts) +{ + struct timespec onems = { 0, 1000000 }; + struct timespec total = { 0, 0 }; + struct timespec unslept; + struct timespec elapsed; + struct timespec tmp; + + while(timespeccmp(ts, &total, >)) + { + if (sem_trywait_SysV(sem) == 0) + { + return(0); + } + + if (errno != EAGAIN) + { + return(-1); + } + + nanosleep(&onems, &unslept); + + timespecsub(&onems, &unslept, &elapsed); + timespecadd(&total, &elapsed, &tmp); + total.tv_sec = tmp.tv_sec; + total.tv_nsec = tmp.tv_nsec; + } + + errno = ETIMEDOUT; + return(-1); +} + int sem_post_SysV(sem_t *semaphore) { @@ -641,6 +791,8 @@ sem_t key_t clef; union semun argument; + + unsigned char *langue; # endif unsigned char *nom_absolu; @@ -659,7 +811,7 @@ sem_t # endif # ifndef OS2 // IPCS_SYSV - if ((nom_absolu = malloc((strlen(racine_segment) + strlen(nom) + if ((nom_absolu = sys_malloc((strlen(racine_segment) + strlen(nom) + 2) * sizeof(unsigned char))) == NULL) { return(SEM_FAILED); @@ -667,7 +819,7 @@ sem_t sprintf(nom_absolu, "%s/%s", racine_segment, nom); - if ((semaphore = malloc(sizeof(sem_t))) == NULL) + if ((semaphore = sys_malloc(sizeof(sem_t))) == NULL) { return(SEM_FAILED); } @@ -676,8 +828,8 @@ sem_t (*semaphore).pid = getpid(); (*semaphore).tid = pthread_self(); # else - if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1) - * sizeof(unsigned char))) == NULL) + if ((nom_segment = sys_malloc((strlen(racine_memoire_OS2) + strlen(nom) + + 1) * sizeof(unsigned char))) == NULL) { return(SEM_FAILED); } @@ -695,8 +847,8 @@ sem_t ptr++; } - if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom) - + 2) * sizeof(unsigned char))) == NULL) + if ((nom_absolu = sys_malloc((strlen(racine_semaphores_OS2) + + strlen(nom) + 2) * sizeof(unsigned char))) == NULL) { return(SEM_FAILED); } @@ -716,7 +868,7 @@ sem_t (*(ptr + 1)) = d_code_fin_chaine; - if ((psem = malloc(sizeof(sem_t))) == NULL) + if ((psem = sys_malloc(sizeof(sem_t))) == NULL) { return(SEM_FAILED); } @@ -742,16 +894,16 @@ sem_t if ((*semaphore).sem == -1) { - free(semaphore); - free(nom_absolu); + sys_free(semaphore); + sys_free(nom_absolu); return(SEM_FAILED); } # else // OS/2 - if ((psem = malloc(sizeof(sem_t))) == NULL) + if ((psem = sys_malloc(sizeof(sem_t))) == NULL) { - free(nom_absolu); - free(nom_segment); + sys_free(nom_absolu); + sys_free(nom_segment); return(SEM_FAILED); } @@ -759,9 +911,9 @@ sem_t if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0) { - free(psem); - free(nom_absolu); - free(nom_segment); + sys_free(psem); + sys_free(nom_absolu); + sys_free(nom_segment); return(SEM_FAILED); } @@ -772,9 +924,9 @@ sem_t { DosCloseMutexSem((*psem).hmtx); - free(psem); - free(nom_absolu); - free(nom_segment); + sys_free(psem); + sys_free(nom_absolu); + sys_free(nom_segment); return(SEM_FAILED); } @@ -784,14 +936,14 @@ sem_t { DosCloseMutexSem((*psem).hmtx); - free(nom_absolu); - free(nom_segment); - free(psem); + sys_free(nom_absolu); + sys_free(nom_segment); + sys_free(psem); return(SEM_FAILED); } - free(nom_segment); + sys_free(nom_segment); (*psem).cnt = (ULONG *) base; (*psem).nopened = ((ULONG *) base) + 1; @@ -801,9 +953,9 @@ sem_t { DosCloseMutexSem((*psem).hmtx); - free(nom_absolu); - free(nom_segment); - free(psem); + sys_free(nom_absolu); + sys_free(nom_segment); + sys_free(psem); return(SEM_FAILED); } @@ -831,17 +983,46 @@ sem_t if ((desc = open(nom_absolu, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR)) == -1) { - free(semaphore); - free(nom_absolu); + if (errno != EEXIST) + { + sys_free(semaphore); + sys_free(nom_absolu); + return(SEM_FAILED); + } - return(SEM_FAILED); + if ((langue = getenv("LANG")) != NULL) + { + if (strncmp(langue, "fr", 2) == 0) + { + uprintf("+++Attention : Le sémaphore %s préexiste !\n", + nom_absolu); + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", + nom_absolu); + } + } + else + { + uprintf("+++Warning: %s semaphore preexists!\n", + nom_absolu); + } + + if ((desc = open(nom_absolu, O_CREAT | O_RDWR, + S_IRUSR | S_IWUSR)) == -1) + { + sys_free(semaphore); + sys_free(nom_absolu); + return(SEM_FAILED); + } } if ((clef = ftok(nom_absolu, 1)) == -1) { close(desc); - free(semaphore); - free(nom_absolu); + sys_free(semaphore); + sys_free(nom_absolu); return(SEM_FAILED); } @@ -857,19 +1038,19 @@ sem_t if ((*semaphore).sem == -1) { - free(semaphore); - free(nom_absolu); + sys_free(semaphore); + sys_free(nom_absolu); return(SEM_FAILED); } - argument.val = valeur; + argument.val = (int) valeur; semctl((*semaphore).sem, 0, SETVAL, argument); # else // OS/2 - if ((psem = malloc(sizeof(sem_t))) == NULL) + if ((psem = sys_malloc(sizeof(sem_t))) == NULL) { - free(nom_absolu); - free(nom_segment); + sys_free(nom_absolu); + sys_free(nom_segment); return(SEM_FAILED); } @@ -878,9 +1059,9 @@ sem_t if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0) { - free(psem); - free(nom_absolu); - free(nom_segment); + sys_free(psem); + sys_free(nom_absolu); + sys_free(nom_segment); return(SEM_FAILED); } @@ -892,9 +1073,9 @@ sem_t { DosCloseMutexSem((*psem).hmtx); - free(nom_absolu); - free(nom_segment); - free(psem); + sys_free(nom_absolu); + sys_free(nom_segment); + sys_free(psem); return(SEM_FAILED); } @@ -904,14 +1085,14 @@ sem_t { DosCloseMutexSem((*psem).hmtx); - free(nom_absolu); - free(nom_segment); - free(psem); + sys_free(nom_absolu); + sys_free(nom_segment); + sys_free(psem); return(SEM_FAILED); } - free(nom_segment); + sys_free(nom_segment); (*psem).cnt = (ULONG *) base; (*psem).nopened = ((ULONG *) base) + 1; @@ -932,12 +1113,12 @@ sem_close_SysV(sem_t *semaphore) # ifndef OS2 // IPCS_SYSV if ((*semaphore).path != NULL) { - free((*semaphore).path); + sys_free((*semaphore).path); } if ((*semaphore).alloue == -1) { - free(semaphore); + sys_free(semaphore); } return(0); @@ -960,8 +1141,8 @@ sem_close_SysV(sem_t *semaphore) if ((*psem).shared == 0) { - free((*psem).cnt); - free((*psem).nopened); + sys_free((*psem).cnt); + sys_free((*psem).nopened); } else { @@ -973,7 +1154,7 @@ sem_close_SysV(sem_t *semaphore) if ((*psem).allocated != 0) { - free(psem); + sys_free(psem); } return(0); @@ -981,7 +1162,7 @@ sem_close_SysV(sem_t *semaphore) } int -sem_unlink_SysV(const char *nom) +sem_unlink_SysV(char *nom) { // Détruit un sémaphore nommé créé par sem_open_SysV() # ifndef OS2 // IPCS_SYSV @@ -989,11 +1170,10 @@ sem_unlink_SysV(const char *nom) if (unlink(nom) == -1) { - free(nom_absolu); return(EACCES); } - free(nom); + sys_free(nom); return(0); # else return(0);