--- rpl/src/semaphores.c 2011/09/19 17:33:17 1.32 +++ rpl/src/semaphores.c 2012/05/31 14:20:33 1.46 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.3 - Copyright (C) 1989-2011 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.9 + Copyright (C) 1989-2012 Dr. BERTRAND Joël This file is part of RPL/2. @@ -22,6 +22,7 @@ #include "rpl-conv.h" + #ifdef SEMAPHORES_NOMMES // Les fonctions suivantes ne sont utilisées que dans le cas d'un @@ -29,7 +30,7 @@ // est dans ce cas. static unsigned char * -nom_segment_semaphore(pid_t pid) +nom_segment_semaphore(pid_t pid, int ordre) { unsigned char *fichier; @@ -38,7 +39,23 @@ nom_segment_semaphore(pid_t pid) return(NULL); } - sprintf(fichier, "/RPL-SIGSEMAPHORE-%d", (int) pid); + sprintf(fichier, "/RPL-%d-%d", (int) pid, ordre); + return(fichier); +} + + +static unsigned char * +nom_segment_semaphore_thread(pid_t pid, pthread_t tid, int ordre) +{ + unsigned char *fichier; + + if ((fichier = malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL) + { + return(NULL); + } + + sprintf(fichier, "/RPL-%d-%llX-%d", (int) pid, + (unsigned long long) tid, ordre); return(fichier); } @@ -56,44 +73,55 @@ nom_segment_semaphore(pid_t pid) */ sem_t * -sem_init2(unsigned int valeur, pid_t pid) +sem_init2(unsigned int valeur, pid_t pid, int ordre) { sem_t *semaphore; unsigned char *chemin; - unsigned int i; - if ((chemin = nom_segment_semaphore(pid)) == NULL) + if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL) { return(SEM_FAILED); } - semaphore = sem_open(chemin, O_CREAT, (S_IRUSR | S_IWUSR), valeur); + semaphore = sem_open(chemin, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, + valeur); free(chemin); - for(i = 0; i < valeur; i++) + return(semaphore); +} + + +sem_t * +sem_init3(unsigned int valeur, pid_t pid, pthread_t tid, int ordre) +{ + sem_t *semaphore; + + unsigned char *chemin; + + if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL) { - if (sem_post(semaphore) != 0) - { - sem_close(semaphore); - return(SEM_FAILED); - } + return(SEM_FAILED); } + semaphore = sem_open(chemin, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR, + valeur); + free(chemin); + return(semaphore); } sem_t * -sem_open2(pid_t pid) +sem_open2(pid_t pid, int ordre) { unsigned char *chemin; sem_t *semaphore; - if ((chemin = nom_segment_semaphore(pid)) == NULL) + if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL) { - return(1); + return(SEM_FAILED); } semaphore = sem_open(chemin, O_RDWR); @@ -104,7 +132,7 @@ sem_open2(pid_t pid) int -sem_destroy2(sem_t *semaphore, pid_t pid) +sem_destroy2(sem_t *semaphore, pid_t pid, int ordre) { int erreur; @@ -112,7 +140,7 @@ sem_destroy2(sem_t *semaphore, pid_t pid sem_close(semaphore); - if ((chemin = nom_segment_semaphore(pid)) == NULL) + if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL) { return(1); } @@ -123,6 +151,28 @@ sem_destroy2(sem_t *semaphore, pid_t pid return(erreur); } + +int +sem_destroy3(sem_t *semaphore, pid_t pid, pthread_t tid, int ordre) +{ + int erreur; + + unsigned char *chemin; + + sem_close(semaphore); + + if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL) + { + return(1); + } + + erreur = sem_unlink(chemin); + free(chemin); + + return(erreur); +} + + #undef sem_post #undef sem_wait #undef sem_trywait @@ -236,21 +286,22 @@ sem_init_SysV(sem_t *semaphore, int shar S_IRUSR | S_IWUSR); (*semaphore).path = NULL; (*semaphore).pid = getpid(); + (*semaphore).tid = pthread_self(); (*semaphore).alloue = 0; } else { // Sémaphore partagé entre plusieurs processus if (((*semaphore).path = malloc((strlen(racine_segment) - + 1 + 32 + 1) * sizeof(unsigned char))) == NULL) + + 2 + 256 + 1) * sizeof(unsigned char))) == NULL) { return(-1); } - sprintf((*semaphore).path, "%s/RPL-SIGSEMAPHORE-%d", racine_segment, - (int) getpid()); + sprintf((*semaphore).path, "%s/RPL-SEMAPHORE-%d-%llX-%d", + racine_segment, (int) getpid(), pthread_self(), shared); - if ((desc = open((*semaphore).path, O_CREAT | O_EXCL | + if ((desc = open((*semaphore).path, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) == -1) { free((*semaphore).path); @@ -258,6 +309,7 @@ sem_init_SysV(sem_t *semaphore, int shar } (*semaphore).pid = getpid(); + (*semaphore).tid = pthread_self(); clef = ftok((*semaphore).path, 1); close(desc); @@ -283,56 +335,49 @@ sem_init_SysV(sem_t *semaphore, int shar return(ios); # else // OS/2 + sem_t *psem; - sem_t *psem; - - psem = semaphore; - - if (shared != 0) - { - errno = ENOSYS; - return(-1); - } + psem = semaphore; - if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL) - { - free(psem); - errno = ENOMEM; - return(-1); - } - - if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL) - { - free((*psem).cnt); - free(psem); - errno = ENOMEM; - return(-1); - } + if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL) + { + free(psem); + errno = ENOMEM; + return(-1); + } - if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0) - { - free((*psem).cnt); - free((*psem).nopened); - free(psem); - return(-1); - } + if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL) + { + free((*psem).cnt); + free(psem); + errno = ENOMEM; + return(-1); + } - if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0) != 0) - { - DosCloseMutexSem((*psem).hmtx); - free((*psem).cnt); - free((*psem).nopened); - free(psem); - return(-1); - } + if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0) + { + free((*psem).cnt); + free((*psem).nopened); + free(psem); + return(-1); + } - (*(*psem).cnt) = valeur; - (*(*psem).nopened) = 1; - (*psem).shared = shared; - (*psem).allocated = 0; + if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0) + != 0) + { + DosCloseMutexSem((*psem).hmtx); + free((*psem).cnt); + free((*psem).nopened); + free(psem); + return(-1); + } - return(0); + (*(*psem).cnt) = valeur; + (*(*psem).nopened) = 1; + (*psem).shared = shared; + (*psem).allocated = 0; + return(0); # endif } @@ -359,48 +404,46 @@ sem_destroy_SysV(sem_t *semaphore) return(0); # else // OS/2 + sem_t *psem; - sem_t *psem; - - psem = semaphore; + psem = semaphore; - if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) - { - return(EINVAL); - } + if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) + { + return(EINVAL); + } - if (DosCloseMutexSem((*psem).hmtx) != 0) - { - return(EINVAL); - } + if (DosCloseMutexSem((*psem).hmtx) != 0) + { + return(EINVAL); + } - while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY) - { - DosPostEventSem((*psem).hev); - } + while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY) + { + DosPostEventSem((*psem).hev); + } - (*(*psem).nopened)--; + (*(*psem).nopened)--; - if ((*psem).shared == 0) - { - free((*psem).cnt); - free((*psem).nopened); - } - else - { - if ((*(*psem).nopened) == 0) + if ((*psem).shared == 0) { - DosFreeMem((*psem).cnt); + free((*psem).cnt); + free((*psem).nopened); + } + else + { + if ((*(*psem).nopened) == 0) + { + DosFreeMem((*psem).cnt); + } } - } - - if ((*psem).allocated != 0) - { - free(psem); - } - return(0); + if ((*psem).allocated != 0) + { + free(psem); + } + return(0); # endif } @@ -425,38 +468,36 @@ sem_wait_SysV(sem_t *semaphore) return(0); # else // OS/2 + sem_t *psem; - sem_t *psem; + ULONG cnt; - ULONG cnt; + psem = semaphore; - psem = semaphore; - - if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0) - { - errno = EINVAL; - return(-1); - } - - if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) - { - errno = EINVAL; - return(-1); - } + if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0) + { + errno = EINVAL; + return(-1); + } - if ((*(*psem).cnt) > 0) - { - (*(*psem).cnt)--; - } + if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) + { + errno = EINVAL; + return(-1); + } - if ((*(*psem).cnt) == 0) - { - DosResetEventSem((*psem).hev, &cnt); - } + if ((*(*psem).cnt) > 0) + { + (*(*psem).cnt)--; + } - DosReleaseMutexSem((*psem).hmtx); - return(0); + if ((*(*psem).cnt) == 0) + { + DosResetEventSem((*psem).hev, &cnt); + } + DosReleaseMutexSem((*psem).hmtx); + return(0); # endif } @@ -481,40 +522,38 @@ sem_trywait_SysV(sem_t *semaphore) return(0); # else // OS/2 + int ios; - int ios; + sem_t *psem; - sem_t *psem; + ULONG cnt; - ULONG cnt; + psem = semaphore; - psem = semaphore; - - if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0) - { - errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL; - return(-1); - } - - if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) - { - errno = EINVAL; - return(-1); - } + if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0) + { + errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL; + return(-1); + } - if ((*(*psem).cnt) > 0) - { - (*(*psem).cnt)--; - } + if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) + { + errno = EINVAL; + return(-1); + } - if ((*(*psem).cnt) == 0) - { - DosResetEventSem((*psem).hev, &cnt); - } + if ((*(*psem).cnt) > 0) + { + (*(*psem).cnt)--; + } - DosReleaseMutexSem((*psem).hmtx); - return(0); + if ((*(*psem).cnt) == 0) + { + DosResetEventSem((*psem).hev, &cnt); + } + DosReleaseMutexSem((*psem).hmtx); + return(0); # endif } @@ -539,23 +578,21 @@ sem_post_SysV(sem_t *semaphore) return(0); # else // OS/2 + sem_t *psem; - sem_t *psem; + psem = semaphore; - psem = semaphore; - - if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) - { - errno = EINVAL; - return(-1); - } - - (*(*psem).cnt)++; - DosPostEventSem((*psem).hev); - DosReleaseMutexSem((*psem).hmtx); + if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) + { + errno = EINVAL; + return(-1); + } - return(0); + (*(*psem).cnt)++; + DosPostEventSem((*psem).hev); + DosReleaseMutexSem((*psem).hmtx); + return(0); # endif } @@ -572,22 +609,20 @@ sem_getvalue_SysV(sem_t *semaphore, int return(0); # else + sem_t *psem; - sem_t *psem; - - psem = semaphore; - - if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) - { - errno = EINVAL; - return(-1); - } + psem = semaphore; - (*valeur) = (*(*psem).cnt); - DosReleaseMutexSem((*psem).hmtx); + if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) + { + errno = EINVAL; + return(-1); + } - return(0); + (*valeur) = (*(*psem).cnt); + DosReleaseMutexSem((*psem).hmtx); + return(0); # endif } @@ -638,55 +673,55 @@ sem_t } (*semaphore).alloue = -1; + (*semaphore).pid = getpid(); + (*semaphore).tid = pthread_self(); # else - - if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1) - * sizeof(unsigned char))) == NULL) - { - return(SEM_FAILED); - } - - sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom); - ptr = nom_segment; - - while((*ptr) != d_code_fin_chaine) - { - if ((*ptr) == '/') + if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1) + * sizeof(unsigned char))) == NULL) { - (*ptr) = '\\'; - } + return(SEM_FAILED); + } - ptr++; - } + sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom); + ptr = nom_segment; - if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom) - + 2) * sizeof(unsigned char))) == NULL) - { - return(SEM_FAILED); - } + while((*ptr) != d_code_fin_chaine) + { + if ((*ptr) == '/') + { + (*ptr) = '\\'; + } - sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom); - ptr = nom_absolu; + ptr++; + } - while((*ptr) != d_code_fin_chaine) - { - if ((*ptr) == '/') + if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom) + + 2) * sizeof(unsigned char))) == NULL) { - (*ptr) = '\\'; + return(SEM_FAILED); } - ptr++; - } + sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom); + ptr = nom_absolu; - (*(ptr + 1)) = d_code_fin_chaine; + while((*ptr) != d_code_fin_chaine) + { + if ((*ptr) == '/') + { + (*ptr) = '\\'; + } - if ((psem = malloc(sizeof(sem_t))) == NULL) - { - return(SEM_FAILED); - } + ptr++; + } - (*psem).allocated = 1; + (*(ptr + 1)) = d_code_fin_chaine; + + if ((psem = malloc(sizeof(sem_t))) == NULL) + { + return(SEM_FAILED); + } + (*psem).allocated = 1; # endif if ((oflag & O_CREAT) == 0) @@ -713,71 +748,71 @@ sem_t return(SEM_FAILED); } # else // OS/2 - if ((psem = malloc(sizeof(sem_t))) == NULL) - { - free(nom_absolu); - free(nom_segment); - return(SEM_FAILED); - } + if ((psem = malloc(sizeof(sem_t))) == NULL) + { + free(nom_absolu); + free(nom_segment); + return(SEM_FAILED); + } - (*ptr) = 'M'; + (*ptr) = 'M'; - if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0) - { - free(psem); - free(nom_absolu); - free(nom_segment); - - return(SEM_FAILED); - } + if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0) + { + free(psem); + free(nom_absolu); + free(nom_segment); - (*ptr) = 'S'; + return(SEM_FAILED); + } - if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0) - { - DosCloseMutexSem((*psem).hmtx); + (*ptr) = 'S'; - free(psem); - free(nom_absolu); - free(nom_segment); + if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0) + { + DosCloseMutexSem((*psem).hmtx); - return(SEM_FAILED); - } + free(psem); + free(nom_absolu); + free(nom_segment); - if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ) != 0) - { - DosCloseMutexSem((*psem).hmtx); + return(SEM_FAILED); + } - free(nom_absolu); - free(nom_segment); - free(psem); + if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ) + != 0) + { + DosCloseMutexSem((*psem).hmtx); - return(SEM_FAILED); - } + free(nom_absolu); + free(nom_segment); + free(psem); - free(nom_segment); + return(SEM_FAILED); + } - (*psem).cnt = (ULONG *) base; - (*psem).nopened = ((ULONG *) base) + 1; - (*psem).shared = 1; + free(nom_segment); - if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) - { - DosCloseMutexSem((*psem).hmtx); + (*psem).cnt = (ULONG *) base; + (*psem).nopened = ((ULONG *) base) + 1; + (*psem).shared = 1; - free(nom_absolu); - free(nom_segment); - free(psem); + if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0) + { + DosCloseMutexSem((*psem).hmtx); - return(SEM_FAILED); - } + free(nom_absolu); + free(nom_segment); + free(psem); - (*((*psem).nopened))++; + return(SEM_FAILED); + } - DosReleaseMutexSem((*psem).hmtx); + (*((*psem).nopened))++; - semaphore = psem; + DosReleaseMutexSem((*psem).hmtx); + semaphore = psem; # endif } else @@ -793,8 +828,8 @@ sem_t va_end(liste); # ifndef OS2 // IPCS_SYSV - if ((desc = open(nom_absolu, O_CREAT | O_EXCL | S_IRUSR | S_IWUSR)) - == -1) + if ((desc = open(nom_absolu, O_CREAT | O_EXCL | O_RDWR, + S_IRUSR | S_IWUSR)) == -1) { free(semaphore); free(nom_absolu); @@ -831,61 +866,59 @@ sem_t argument.val = valeur; semctl((*semaphore).sem, 0, SETVAL, argument); # else // OS/2 + if ((psem = malloc(sizeof(sem_t))) == NULL) + { + free(nom_absolu); + free(nom_segment); - if ((psem = malloc(sizeof(sem_t))) == NULL) - { - free(nom_absolu); - free(nom_segment); - - return(SEM_FAILED); - } - - (*ptr) = 'M'; + return(SEM_FAILED); + } - if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0) - { - free(psem); - free(nom_absolu); - free(nom_segment); + (*ptr) = 'M'; - return(SEM_FAILED); - } + if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0) + { + free(psem); + free(nom_absolu); + free(nom_segment); - (*ptr) = 'S'; + return(SEM_FAILED); + } - if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0, - (valeur != 0) ? 1 : 0) != 0) - { - DosCloseMutexSem((*psem).hmtx); + (*ptr) = 'S'; - free(nom_absolu); - free(nom_segment); - free(psem); + if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0, + (valeur != 0) ? 1 : 0) != 0) + { + DosCloseMutexSem((*psem).hmtx); - return(SEM_FAILED); - } + free(nom_absolu); + free(nom_segment); + free(psem); - if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG), - PAG_WRITE | PAG_READ | PAG_COMMIT) != 0) - { - DosCloseMutexSem((*psem).hmtx); + return(SEM_FAILED); + } - free(nom_absolu); - free(nom_segment); - free(psem); + if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG), + PAG_WRITE | PAG_READ | PAG_COMMIT) != 0) + { + DosCloseMutexSem((*psem).hmtx); - return(SEM_FAILED); - } + free(nom_absolu); + free(nom_segment); + free(psem); - free(nom_segment); + return(SEM_FAILED); + } - (*psem).cnt = (ULONG *) base; - (*psem).nopened = ((ULONG *) base) + 1; - (*(*psem).cnt) = valeur; - (*(*psem).nopened) = 1; - (*psem).shared = 1; - semaphore = psem; + free(nom_segment); + (*psem).cnt = (ULONG *) base; + (*psem).nopened = ((ULONG *) base) + 1; + (*(*psem).cnt) = valeur; + (*(*psem).nopened) = 1; + (*psem).shared = 1; + semaphore = psem; # endif } @@ -909,43 +942,41 @@ sem_close_SysV(sem_t *semaphore) return(0); # else + sem_t *psem; - sem_t *psem; - - psem = semaphore; + psem = semaphore; - if (DosCloseMutexSem((*psem).hmtx) != 0) - { - return(EINVAL); - } + if (DosCloseMutexSem((*psem).hmtx) != 0) + { + return(EINVAL); + } - while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY) - { - DosPostEventSem((*psem).hev); - } + while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY) + { + DosPostEventSem((*psem).hev); + } - (*(*psem).nopened)--; + (*(*psem).nopened)--; - if ((*psem).shared == 0) - { - free((*psem).cnt); - free((*psem).nopened); - } - else - { - if ((*(*psem).nopened) == 0) + if ((*psem).shared == 0) { - DosFreeMem((*psem).cnt); + free((*psem).cnt); + free((*psem).nopened); + } + else + { + if ((*(*psem).nopened) == 0) + { + DosFreeMem((*psem).cnt); + } } - } - - if ((*psem).allocated != 0) - { - free(psem); - } - return(0); + if ((*psem).allocated != 0) + { + free(psem); + } + return(0); # endif } @@ -954,29 +985,17 @@ sem_unlink_SysV(const char *nom) { // Détruit un sémaphore nommé créé par sem_open_SysV() # ifndef OS2 // IPCS_SYSV - unsigned char *nom_absolu; + semctl(semget(ftok(nom, 1), 0, 0), 0, IPC_RMID); - if ((nom_absolu = malloc((strlen(racine_segment) + strlen(nom) - + 2) * sizeof(unsigned char))) == NULL) + if (unlink(nom) == -1) { - return(ENOMEM); - } - - sprintf(nom_absolu, "%s/%s", racine_segment, nom); - semctl(semget(ftok(nom_absolu, 1), 0, 0), 0, IPC_RMID); - - if (unlink(nom_absolu) == -1) - { - free(nom_absolu); return(EACCES); } - free(nom_absolu); + free(nom); return(0); # else - - return(0); - + return(0); # endif }