--- rpl/src/semaphores.c 2011/11/26 10:01:33 1.40 +++ rpl/src/semaphores.c 2013/02/22 19:48:22 1.53 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.5 - Copyright (C) 1989-2011 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.12 + Copyright (C) 1989-2012 Dr. BERTRAND Joël This file is part of RPL/2. @@ -298,8 +298,10 @@ sem_init_SysV(sem_t *semaphore, int shar 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) @@ -453,17 +455,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 +519,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 +561,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) { @@ -981,7 +1043,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,7 +1051,6 @@ sem_unlink_SysV(const char *nom) if (unlink(nom) == -1) { - free(nom_absolu); return(EACCES); }