Diff for /rpl/src/semaphores.c between versions 1.28 and 1.89

version 1.28, 2011/08/09 11:31:37 version 1.89, 2020/01/10 11:15:51
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.3    RPL/2 (R) version 4.1.32
   Copyright (C) 1989-2011 Dr. BERTRAND Joël    Copyright (C) 1989-2020 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
   
Line 22 Line 22
   
 #include "rpl-conv.h"  #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.
   
   static unsigned char *
   nom_segment_semaphore(pid_t pid, int ordre)
   {
       unsigned char               *fichier;
   
       if ((fichier = sys_malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL)
       {
           return(NULL);
       }
   
       sprintf(fichier, "/RPL-%llu-%d", (unsigned long long) pid, ordre);
       return(fichier);
   }
   
   
   static unsigned char *
   nom_segment_semaphore_thread(pid_t pid, pthread_t tid, int ordre)
   {
       unsigned char               *fichier;
   
       if ((fichier = sys_malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL)
       {
           return(NULL);
       }
   
       sprintf(fichier, "/RPL-%llu-%llu-%d", (unsigned long long) pid,
               (unsigned long long) tid, ordre);
       return(fichier);
   }
   
   
 /*  /*
 ================================================================================  ================================================================================
Line 37 Line 71
 */  */
   
 sem_t *  sem_t *
 sem_init2(unsigned int valeur, enum t_semaphore semaphore)  sem_init2(unsigned int valeur, pid_t pid, int ordre)
   {
       sem_t                       *semaphore;
   
       unsigned char               *chemin;
       unsigned char               *langue;
   
       if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
       {
           return(SEM_FAILED);
       }
   
       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);
   }
   
   
   sem_t *
   sem_init3(unsigned int valeur, pid_t pid, pthread_t tid, int ordre)
   {
       sem_t                       *semaphore;
   
       unsigned char               *chemin;
       unsigned char               *langue;
   
       if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL)
       {
           return(SEM_FAILED);
       }
   
       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);
   }
   
   
   sem_t *
   sem_open2(pid_t pid, int ordre)
   {
       unsigned char               *chemin;
   
       sem_t                       *semaphore;
   
       if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
       {
           return(SEM_FAILED);
       }
   
       semaphore = sem_open(chemin, O_RDWR);
       sys_free(chemin);
   
       return(semaphore);
   }
   
   
   int
   sem_destroy2(sem_t *semaphore, pid_t pid, int ordre)
 {  {
     snprintf(noms_semaphores[semaphore], LONGUEUR_NOM_SEMAPHORE,      int                         erreur;
             "/RPL-SEM-%d-%llu-%d", (int) getpid(),  
             (unsigned long long) pthread_self(),      unsigned char               *chemin;
             (int) semaphore);  
     return(sem_open(noms_semaphores[semaphore], O_CREAT,      sem_close(semaphore);
             (S_IRUSR | S_IWUSR), valeur));  
       if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
       {
           return(1);
       }
   
       erreur = sem_unlink(chemin);
       sys_free(chemin);
   
       return(erreur);
 }  }
   
   
 int  int
 sem_destroy2(sem_t *semaphore_p, enum t_semaphore semaphore)  sem_destroy3(sem_t *semaphore, pid_t pid, pthread_t tid, int ordre)
 {  {
     sem_close(semaphore_p);      int                         erreur;
     return(sem_unlink(noms_semaphores[semaphore]));  
       unsigned char               *chemin;
   
       sem_close(semaphore);
   
       if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL)
       {
           return(1);
       }
   
       erreur = sem_unlink(chemin);
       sys_free(chemin);
   
       return(erreur);
 }  }
   
 #undef sem_post  
 #undef sem_wait  
 #undef sem_trywait  
   
 int  int
 sem_getvalue2(sem_t *semaphore, int *valeur)  sem_getvalue2(sem_t *semaphore, int *valeur)
 {  {
     int                     i;      int                     i;
       int                     j;
   
     logical1                drapeau_fin;      logical1                drapeau_fin;
   
     pthread_mutex_lock(&mutex_sem);      struct timespec         attente;
   
     (*valeur) = 0;      attente.tv_sec = 0;
     drapeau_fin = d_faux;      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                  if (sem_trywait(semaphore) == -1)
                 drapeau_fin = d_vrai;                  {
             }                      if (errno == EAGAIN)
             else                      {
                           // 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                  if (sem_post(semaphore) != 0)
                 pthread_mutex_unlock(&mutex_sem);                  {
                 return(-1);                      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);              pthread_mutex_unlock(&mutex_sem);
             return(-1);              return(0);
         }          }
   
           nanosleep(&attente, NULL);
           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);      return(0);
 }  }
   
 #endif  
   #undef sem_post
   #undef sem_wait
   #undef sem_trywait
   
   
 #ifdef IPCS_SYSV  #ifdef IPCS_SYSV
   
Line 121  sem_getvalue2(sem_t *semaphore, int *val Line 315  sem_getvalue2(sem_t *semaphore, int *val
 ================================================================================  ================================================================================
 */  */
   
 #ifndef OS2  #ifndef OS2 // IPCS_SYSV
     extern unsigned char *chemin_semaphores_SysV;      extern unsigned char *racine_segment;
 #else  #else // OS/2
     unsigned char racine_semaphores_OS2[] = "\\SEM32\\";      unsigned char racine_semaphores_OS2[] = "\\SEM32\\";
     unsigned char racine_memoire_OS2[] = "\\SHAREMEM\\";      unsigned char racine_memoire_OS2[] = "\\SHAREMEM\\";
 #endif  #endif
Line 133  sem_init_SysV(sem_t *semaphore, int shar Line 327  sem_init_SysV(sem_t *semaphore, int shar
 {  {
     // Création d'un sémaphore anonyme qui devra être supprimé par      // Création d'un sémaphore anonyme qui devra être supprimé par
     // sem_destroy_SysV      // sem_destroy_SysV
 #   ifndef OS2  
   
     int             ios;  #   ifndef OS2 // IPCS_SYSV
           int             desc;
           int             ios;
   
     union semun     argument;          key_t           clef;
   
     if (shared != 0)          union semun     argument;
     {  
         errno = ENOSYS;  
         return(-1);  
     }  
   
     (*semaphore).sem = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL |          unsigned char   *langue;
             S_IRUSR | S_IWUSR);  
     (*semaphore).path = NULL;  
     (*semaphore).pid = getpid();  
   
     if ((*semaphore).sem == -1)          if (shared == 0)
     {          {
         errno = EINVAL;              // Sémaphore privé
         return(-1);              (*semaphore).sem = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL |
     }                      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 = sys_malloc((strlen(racine_segment)
                       + 2 + 256 + 1) * sizeof(unsigned char))) == NULL)
               {
                   return(-1);
               }
   
     argument.val = valeur;              sprintf((*semaphore).path, "%s/RPL-SEMAPHORE-%d-%llX-%llX",
     ios = semctl((*semaphore).sem, 0, SETVAL, argument);                      racine_segment, (int) getpid(),
                       (long long unsigned) pthread_self(),
                       (long long unsigned) semaphore);
   
     return(ios);              if ((desc = open((*semaphore).path, O_RDWR | O_CREAT | O_EXCL,
                       S_IRUSR | S_IWUSR)) == -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);
                   }
               }
   
 #   else              (*semaphore).pid = getpid();
               (*semaphore).tid = pthread_self();
               clef = ftok((*semaphore).path, 1);
               close(desc);
   
     sem_t           *psem;              if (clef == -1)
               {
                   sys_free((*semaphore).path);
                   return(-1);
               }
   
     psem = semaphore;              (*semaphore).alloue = 0;
               (*semaphore).sem = semget(clef, 1, IPC_CREAT | IPC_EXCL |
                       S_IRUSR | S_IWUSR);
           }
   
     if (shared != 0)          if ((*semaphore).sem == -1)
     {          {
         errno = ENOSYS;              errno = EINVAL;
         return(-1);              return(-1);
     }          }
   
     if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL)          argument.val = (int) valeur;
     {          ios = semctl((*semaphore).sem, 0, SETVAL, argument);
         free(psem);  
         errno = ENOMEM;  
         return(-1);  
     }  
   
     if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL)          return(ios);
     {  #   else // OS/2
         free((*psem).cnt);          sem_t           *psem;
         free(psem);  
         errno = ENOMEM;  
         return(-1);  
     }  
   
     if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0)          psem = semaphore;
     {  
         free((*psem).cnt);  
         free((*psem).nopened);  
         free(psem);  
         return(-1);  
     }  
   
     if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0) != 0)          if (((*psem).cnt = sys_malloc(sizeof(ULONG))) == NULL)
     {          {
         DosCloseMutexSem((*psem).hmtx);              sys_free(psem);
         free((*psem).cnt);              errno = ENOMEM;
         free((*psem).nopened);              return(-1);
         free(psem);          }
         return(-1);  
     }  
   
     (*(*psem).cnt) = valeur;          if (((*psem).nopened = sys_malloc(sizeof(ULONG))) == NULL)
     (*(*psem).nopened) = 1;          {
     (*psem).shared = shared;              sys_free((*psem).cnt);
     (*psem).allocated = 0;              sys_free(psem);
               errno = ENOMEM;
               return(-1);
           }
   
     return(0);          if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0)
           {
               sys_free((*psem).cnt);
               sys_free((*psem).nopened);
               sys_free(psem);
               return(-1);
           }
   
           if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0)
                   != 0)
           {
               DosCloseMutexSem((*psem).hmtx);
               sys_free((*psem).cnt);
               sys_free((*psem).nopened);
               sys_free(psem);
               return(-1);
           }
   
           (*(*psem).cnt) = valeur;
           (*(*psem).nopened) = 1;
           (*psem).shared = shared;
           (*psem).allocated = 0;
   
           return(0);
 #   endif  #   endif
 }  }
   
Line 219  int Line 475  int
 sem_destroy_SysV(sem_t *semaphore)  sem_destroy_SysV(sem_t *semaphore)
 {  {
     // Détruit un sémaphore anonmyme      // Détruit un sémaphore anonmyme
 #   ifndef OS2  
   
     if ((*semaphore).path != NULL)  
     {  
         return(EINVAL);  
     }  
   
     if ((*semaphore).pid != getpid())  
     {  
         return(0);  
     }  
   
     if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)  #   ifndef OS2 // IPCS_SYSV
     {          if ((*semaphore).path != NULL)
         return(EINVAL);          {
     }              return(EINVAL);
           }
   
     return(0);          if ((*semaphore).pid != getpid())
           {
               return(0);
           }
   
 #   else          if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)
           {
               return(EINVAL);
           }
   
     sem_t       *psem;          return(0);
   #   else // OS/2
           sem_t       *psem;
   
     psem = semaphore;          psem = semaphore;
   
     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)          if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
     {          {
         return(EINVAL);              return(EINVAL);
     }          }
   
     if (DosCloseMutexSem((*psem).hmtx) != 0)          if (DosCloseMutexSem((*psem).hmtx) != 0)
     {          {
         return(EINVAL);              return(EINVAL);
     }          }
   
     while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)          while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
     {          {
         DosPostEventSem((*psem).hev);              DosPostEventSem((*psem).hev);
     }          }
   
     (*(*psem).nopened)--;          (*(*psem).nopened)--;
   
     if ((*psem).shared == 0)          if ((*psem).shared == 0)
     {  
         free((*psem).cnt);  
         free((*psem).nopened);  
     }  
     else  
     {  
         if ((*(*psem).nopened) == 0)  
         {          {
             DosFreeMem((*psem).cnt);              sys_free((*psem).cnt);
               sys_free((*psem).nopened);
           }
           else
           {
               if ((*(*psem).nopened) == 0)
               {
                   DosFreeMem((*psem).cnt);
               }
         }          }
     }  
   
     if ((*psem).allocated != 0)  
     {     
         free(psem);  
     }  
   
     return(0);          if ((*psem).allocated != 0)
           {   
               sys_free(psem);
           }
   
           return(0);
 #   endif  #   endif
 }  }
   
 int  int
 sem_wait_SysV(sem_t *semaphore)  sem_wait_SysV(sem_t *semaphore)
 {  {
 #   ifndef OS2  #   ifndef OS2 // IPCS_SYSV
           struct sembuf       commande;
   
     struct sembuf       commande;          // semop() ne renvoie pas EINTR sur un signal !
   
     commande.sem_num = 0;          commande.sem_num = 0;
     commande.sem_op = -1;          commande.sem_op = -1;
     commande.sem_flg = 0;          commande.sem_flg = 0;
   
     while(semop((*semaphore).sem, &commande, 1) == -1)          if (semop((*semaphore).sem, &commande, 1) == -1)
     {  
         if (errno != EINTR)  
         {          {
             errno = EINVAL;              if (errno != EAGAIN)
             return(-1);              {
                   errno = EINVAL;
                   return(-1);
               }
               else
               {
                   return(-1);
               }
         }          }
     }  
   
     return(0);  
   
 #   else          return(0);
   #   else // OS/2
     sem_t       *psem;          sem_t       *psem;
   
     ULONG       cnt;  
   
     psem = semaphore;          ULONG       cnt;
   
     if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)          psem = semaphore;
     {  
         errno = EINVAL;  
         return(-1);  
     }  
   
     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)          if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)
     {          {
         errno = EINVAL;              errno = EINVAL;
         return(-1);              return(-1);
     }          }
   
     if ((*(*psem).cnt) > 0)          if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
     {          {
         (*(*psem).cnt)--;              errno = EINVAL;
     }              return(-1);
           }
   
     if ((*(*psem).cnt) == 0)          if ((*(*psem).cnt) > 0)
     {          {
         DosResetEventSem((*psem).hev, &cnt);              (*(*psem).cnt)--;
     }          }
   
     DosReleaseMutexSem((*psem).hmtx);          if ((*(*psem).cnt) == 0)
     return(0);          {
               DosResetEventSem((*psem).hev, &cnt);
           }
   
           DosReleaseMutexSem((*psem).hmtx);
           return(0);
 #   endif  #   endif
 }  }
   
 int  int
 sem_trywait_SysV(sem_t *semaphore)  sem_trywait_SysV(sem_t *semaphore)
 {  {
 #   ifndef OS2  #   ifndef OS2 // IPCS_SYSV
           struct sembuf       commande;
     struct sembuf       commande;  
   
     commande.sem_num = 0;          commande.sem_num = 0;
     commande.sem_op = -1;          commande.sem_op = -1;
     commande.sem_flg = IPC_NOWAIT;          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);  
   
 #   else  
   
     int         ios;  
   
     sem_t       *psem;          return(0);
   #   else // OS/2
           int         ios;
   
     ULONG       cnt;          sem_t       *psem;
   
     psem = semaphore;          ULONG       cnt;
   
     if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)          psem = semaphore;
     {  
         errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;  
         return(-1);  
     }  
   
     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)          if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)
     {          {
         errno = EINVAL;              errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;
         return(-1);              return(-1);
     }          }
   
     if ((*(*psem).cnt) > 0)          if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
     {          {
         (*(*psem).cnt)--;              errno = EINVAL;
     }              return(-1);
           }
   
     if ((*(*psem).cnt) == 0)          if ((*(*psem).cnt) > 0)
     {          {
         DosResetEventSem((*psem).hev, &cnt);              (*(*psem).cnt)--;
     }          }
   
     DosReleaseMutexSem((*psem).hmtx);          if ((*(*psem).cnt) == 0)
     return(0);          {
               DosResetEventSem((*psem).hev, &cnt);
           }
   
           DosReleaseMutexSem((*psem).hmtx);
           return(0);
 #   endif  #   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  int
 sem_post_SysV(sem_t *semaphore)  sem_timedwait_SysV(sem_t *sem, struct timespec *ts)
 {  {
 #   ifndef OS2      struct timespec onems = { 0, 1000000 };
       struct timespec total = { 0, 0 };
     struct sembuf       commande;      struct timespec unslept;
       struct timespec elapsed;
       struct timespec tmp;
   
     commande.sem_num = 0;      while(timespeccmp(ts, &total, >))
     commande.sem_op = 1;  
     commande.sem_flg = 0;  
   
     while(semop((*semaphore).sem, &commande, 1) == -1)  
     {      {
         if (errno != EINTR)          if (sem_trywait_SysV(sem) == 0)
           {
               return(0);
           }
   
           if (errno != EAGAIN)
         {          {
             errno = EINVAL;  
             return(-1);              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;
     }      }
   
     return(0);      errno = ETIMEDOUT;
       return(-1);
   }
   
 #   else  int
   sem_post_SysV(sem_t *semaphore)
   {
   #   ifndef OS2 // IPCS_SYSV
           struct sembuf       commande;
   
     sem_t               *psem;          commande.sem_num = 0;
           commande.sem_op = 1;
           commande.sem_flg = 0;
   
     psem = semaphore;          while(semop((*semaphore).sem, &commande, 1) == -1)
           {
               if (errno != EINTR)
               {
                   errno = EINVAL;
                   return(-1);
               }
           }
   
     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)          return(0);
     {  #   else // OS/2
         errno = EINVAL;          sem_t               *psem;
         return(-1);  
     }  
   
     (*(*psem).cnt)++;          psem = semaphore;
     DosPostEventSem((*psem).hev);  
     DosReleaseMutexSem((*psem).hmtx);  
   
     return(0);          if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
           {
               errno = EINVAL;
               return(-1);
           }
   
           (*(*psem).cnt)++;
           DosPostEventSem((*psem).hev);
           DosReleaseMutexSem((*psem).hmtx);
   
           return(0);
 #   endif  #   endif
 }  }
   
 int  int
 sem_getvalue_SysV(sem_t *semaphore, int *valeur)  sem_getvalue_SysV(sem_t *semaphore, int *valeur)
 {  {
 #   ifndef OS2  #   ifndef OS2 // IPCS_SYSV
           (*valeur) = semctl((*semaphore).sem, 0, GETVAL);
   
     (*valeur) = semctl((*semaphore).sem, 0, GETVAL);          if ((*valeur) < 0)
           {
     if ((*valeur) < 0)              return(EINVAL);
     {          }
         return(EINVAL);  
     }  
   
     return(0);  
   
           return(0);
 #   else  #   else
           sem_t               *psem;
   
     sem_t               *psem;          psem = semaphore;
   
     psem = semaphore;          if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
           {
     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)              errno = EINVAL;
     {              return(-1);
         errno = EINVAL;          }
         return(-1);  
     }  
   
     (*valeur) = (*(*psem).cnt);  
     DosReleaseMutexSem((*psem).hmtx);  
   
     return(0);          (*valeur) = (*(*psem).cnt);
           DosReleaseMutexSem((*psem).hmtx);
   
           return(0);
 #   endif  #   endif
 }  }
   
Line 489  sem_t Line 786  sem_t
     sem_t               *semaphore;      sem_t               *semaphore;
   
 #   ifndef OS2  #   ifndef OS2
     file                *desc;          int             desc;
   
     key_t               clef;          key_t           clef;
   
     union semun         argument;          union semun     argument;
   
           unsigned char   *langue;
 #   endif  #   endif
   
     unsigned char       *nom_absolu;      unsigned char       *nom_absolu;
Line 503  sem_t Line 802  sem_t
     va_list             liste;      va_list             liste;
   
 #   ifdef OS2  #   ifdef OS2
     sem_t               *psem;          sem_t           *psem;
   
     PVOID               base;          PVOID           base;
   
     unsigned char       *ptr;          unsigned char   *ptr;
     unsigned char       *nom_segment;          unsigned char   *nom_segment;
 #   endif  #   endif
   
 #   ifndef OS2  #   ifndef OS2 // IPCS_SYSV
           if ((nom_absolu = sys_malloc((strlen(racine_segment) + strlen(nom)
     if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)                  + 2) * sizeof(unsigned char))) == NULL)
             + 1) * sizeof(unsigned char))) == NULL)          {
     {              return(SEM_FAILED);
         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)          if ((semaphore = sys_malloc(sizeof(sem_t))) == NULL)
     {          {
         return(SEM_FAILED);              return(SEM_FAILED);
     }          }
   
           (*semaphore).alloue = -1;
           (*semaphore).pid = getpid();
           (*semaphore).tid = pthread_self();
 #   else  #   else
           if ((nom_segment = sys_malloc((strlen(racine_memoire_OS2) + strlen(nom)
     if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1)                  + 1) * sizeof(unsigned char))) == NULL)
             * 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) == '/')  
         {          {
             (*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)          while((*ptr) != d_code_fin_chaine)
             + 2) * sizeof(unsigned char))) == NULL)          {
     {              if ((*ptr) == '/')
         return(SEM_FAILED);              {
     }                  (*ptr) = '\\';
               }
   
     sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom);              ptr++;
     ptr = nom_absolu;          }
   
     while((*ptr) != d_code_fin_chaine)          if ((nom_absolu = sys_malloc((strlen(racine_semaphores_OS2) +
     {                  strlen(nom) + 2) * sizeof(unsigned char))) == NULL)
         if ((*ptr) == '/')  
         {          {
             (*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)              ptr++;
     {          }
         return(SEM_FAILED);  
     }  
   
     (*psem).allocated = 1;          (*(ptr + 1)) = d_code_fin_chaine;
   
           if ((psem = sys_malloc(sizeof(sem_t))) == NULL)
           {
               return(SEM_FAILED);
           }
   
           (*psem).allocated = 1;
 #   endif  #   endif
   
     if ((oflag & O_CREAT) == 0)      if ((oflag & O_CREAT) == 0)
     {      {
         // 2 arguments          // 2 arguments
   
 #       ifndef OS2  #       ifndef OS2 // IPCS_SYSV
               clef = ftok(nom_absolu, 1);
         clef = ftok(nom_absolu, 1);  
   
         if (clef == -1)              if (clef == -1)
         {              {
             return(SEM_FAILED);                  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);  
   
             return(SEM_FAILED);  
         }  
   
 #       else              (*semaphore).sem = semget(clef, 0, 0);
               (*semaphore).path = nom_absolu;
               (*semaphore).pid = getpid();
   
               if ((*semaphore).sem == -1)
               {   
                   sys_free(semaphore);
                   sys_free(nom_absolu);
   
         if ((psem = malloc(sizeof(sem_t))) == NULL)                  return(SEM_FAILED);
         {              }
             free(nom_absolu);  #       else // OS/2
             free(nom_segment);              if ((psem = sys_malloc(sizeof(sem_t))) == NULL)
             return(SEM_FAILED);              {
         }                  sys_free(nom_absolu);
                   sys_free(nom_segment);
                   return(SEM_FAILED);
               }
   
         (*ptr) = 'M';              (*ptr) = 'M';
   
         if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)              if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)
         {              {
             free(psem);                  sys_free(psem);
             free(nom_absolu);                  sys_free(nom_absolu);
             free(nom_segment);                  sys_free(nom_segment);
   
             return(SEM_FAILED);                  return(SEM_FAILED);
         }              }
   
         (*ptr) = 'S';              (*ptr) = 'S';
   
         if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)              if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)
         {              {
             DosCloseMutexSem((*psem).hmtx);                  DosCloseMutexSem((*psem).hmtx);
   
             free(psem);                  sys_free(psem);
             free(nom_absolu);                  sys_free(nom_absolu);
             free(nom_segment);                  sys_free(nom_segment);
   
             return(SEM_FAILED);                  return(SEM_FAILED);
         }              }
   
         if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ) != 0)              if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ)
         {                      != 0)
             DosCloseMutexSem((*psem).hmtx);              {
                   DosCloseMutexSem((*psem).hmtx);
   
             free(nom_absolu);                  sys_free(nom_absolu);
             free(nom_segment);                  sys_free(nom_segment);
             free(psem);                  sys_free(psem);
   
             return(SEM_FAILED);                  return(SEM_FAILED);
         }              }
   
         free(nom_segment);              sys_free(nom_segment);
   
         (*psem).cnt = (ULONG *) base;              (*psem).cnt = (ULONG *) base;
         (*psem).nopened = ((ULONG *) base) + 1;              (*psem).nopened = ((ULONG *) base) + 1;
         (*psem).shared = 1;              (*psem).shared = 1;
   
         if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)              if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
         {              {
             DosCloseMutexSem((*psem).hmtx);                  DosCloseMutexSem((*psem).hmtx);
   
             free(nom_absolu);  
             free(nom_segment);  
             free(psem);  
   
             return(SEM_FAILED);                  sys_free(nom_absolu);
         }                  sys_free(nom_segment);
                   sys_free(psem);
   
         (*((*psem).nopened))++;                  return(SEM_FAILED);
               }
   
         DosReleaseMutexSem((*psem).hmtx);              (*((*psem).nopened))++;
   
         semaphore = psem;              DosReleaseMutexSem((*psem).hmtx);
   
               semaphore = psem;
 #       endif  #       endif
     }      }
     else      else
Line 683  sem_t Line 979  sem_t
         valeur = va_arg(liste, unsigned int);          valeur = va_arg(liste, unsigned int);
         va_end(liste);          va_end(liste);
   
 #       ifndef OS2  #       ifndef OS2 // IPCS_SYSV
               if ((desc = open(nom_absolu, O_CREAT | O_EXCL | O_RDWR,
         if ((desc = fopen(nom_absolu, "w")) == NULL)                      S_IRUSR | S_IWUSR)) == -1)
         {              {
             free(semaphore);                  if (errno != EEXIST)
             free(nom_absolu);                  {
                       sys_free(semaphore);
             return(SEM_FAILED);                      sys_free(nom_absolu);
         }                      return(SEM_FAILED);
                   }
         fclose(desc);  
                   if ((langue = getenv("LANG")) != NULL)
         if ((clef = ftok(nom_absolu, 1)) == -1)                  {
         {                      if (strncmp(langue, "fr", 2) == 0)
             free(semaphore);                      {
             free(nom_absolu);                          uprintf("+++Attention : Le sémaphore %s préexiste !\n",
                                   nom_absolu);
             return(SEM_FAILED);                      }
         }                      else
                       {
         (*semaphore).sem = semget(clef, 1,                          uprintf("+++Warning: %s semaphore preexists!\n",
                 (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) |                                  nom_absolu);
                 (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) |                      }
                 (int) mode);                  }
         (*semaphore).path = nom_absolu;                  else
         (*semaphore).pid = getpid();                  {
                       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 ((*semaphore).sem == -1)              if ((clef = ftok(nom_absolu, 1)) == -1)
         {                 {
             free(semaphore);                  close(desc);
             free(nom_absolu);                  sys_free(semaphore);
                   sys_free(nom_absolu);
   
             return(SEM_FAILED);                  return(SEM_FAILED);
         }              }
   
         argument.val = valeur;              close(desc);
         semctl((*semaphore).sem, 0, SETVAL, argument);  
   
 #       else              (*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)
               {   
                   sys_free(semaphore);
                   sys_free(nom_absolu);
   
         if ((psem = malloc(sizeof(sem_t))) == NULL)                  return(SEM_FAILED);
         {              }
             free(nom_absolu);  
             free(nom_segment);  
   
             return(SEM_FAILED);              argument.val = (int) valeur;
         }              semctl((*semaphore).sem, 0, SETVAL, argument);
   #       else // OS/2
               if ((psem = sys_malloc(sizeof(sem_t))) == NULL)
               {
                   sys_free(nom_absolu);
                   sys_free(nom_segment);
   
         (*ptr) = 'M';                  return(SEM_FAILED);
               }
   
         if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)              (*ptr) = 'M';
         {  
             free(psem);  
             free(nom_absolu);  
             free(nom_segment);  
   
             return(SEM_FAILED);              if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)
         }              {
                   sys_free(psem);
                   sys_free(nom_absolu);
                   sys_free(nom_segment);
   
         (*ptr) = 'S';                  return(SEM_FAILED);
               }
   
         if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,              (*ptr) = 'S';
                 (valeur != 0) ? 1 : 0) != 0)  
         {  
             DosCloseMutexSem((*psem).hmtx);  
   
             free(nom_absolu);              if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,
             free(nom_segment);                      (valeur != 0) ? 1 : 0) != 0)
             free(psem);              {
                   DosCloseMutexSem((*psem).hmtx);
   
             return(SEM_FAILED);                  sys_free(nom_absolu);
         }                  sys_free(nom_segment);
                   sys_free(psem);
   
         if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),                  return(SEM_FAILED);
                 PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)              }
         {  
             DosCloseMutexSem((*psem).hmtx);  
   
             free(nom_absolu);              if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),
             free(nom_segment);                      PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
             free(psem);              {
                   DosCloseMutexSem((*psem).hmtx);
   
             return(SEM_FAILED);                  sys_free(nom_absolu);
         }                  sys_free(nom_segment);
                   sys_free(psem);
   
         free(nom_segment);                  return(SEM_FAILED);
               }
   
         (*psem).cnt = (ULONG *) base;              sys_free(nom_segment);
         (*psem).nopened = ((ULONG *) base) + 1;  
         (*(*psem).cnt) = valeur;  
         (*(*psem).nopened) = 1;  
         (*psem).shared = 1;  
         semaphore = psem;  
   
               (*psem).cnt = (ULONG *) base;
               (*psem).nopened = ((ULONG *) base) + 1;
               (*(*psem).cnt) = valeur;
               (*(*psem).nopened) = 1;
               (*psem).shared = 1;
               semaphore = psem;
 #       endif  #       endif
     }      }
   
Line 787  int Line 1110  int
 sem_close_SysV(sem_t *semaphore)  sem_close_SysV(sem_t *semaphore)
 {  {
     // Ferme un sémaphore nommé créé par sem_open_SysV()      // Ferme un sémaphore nommé créé par sem_open_SysV()
 #   ifndef OS2  #   ifndef OS2 // IPCS_SYSV
           if ((*semaphore).path != NULL)
     if ((*semaphore).path != NULL)          {
     {              sys_free((*semaphore).path);
         free((*semaphore).path);          }
     }  
   
     free(semaphore);          if ((*semaphore).alloue == -1)
     return(0);          {
               sys_free(semaphore);
           }
   
           return(0);
 #   else  #   else
           sem_t       *psem;
   
     sem_t       *psem;          psem = semaphore;
   
     psem = semaphore;          if (DosCloseMutexSem((*psem).hmtx) != 0)
           {
     if (DosCloseMutexSem((*psem).hmtx) != 0)              return(EINVAL);
     {          }
         return(EINVAL);  
     }  
   
     while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)          while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
     {          {
         DosPostEventSem((*psem).hev);              DosPostEventSem((*psem).hev);
     }          }
   
     (*(*psem).nopened)--;          (*(*psem).nopened)--;
   
     if ((*psem).shared == 0)          if ((*psem).shared == 0)
     {  
         free((*psem).cnt);  
         free((*psem).nopened);  
     }  
     else  
     {  
         if ((*(*psem).nopened) == 0)  
         {          {
             DosFreeMem((*psem).cnt);              sys_free((*psem).cnt);
               sys_free((*psem).nopened);
           }
           else
           {
               if ((*(*psem).nopened) == 0)
               {
                   DosFreeMem((*psem).cnt);
               }
         }          }
     }  
   
     if ((*psem).allocated != 0)  
     {  
         free(psem);  
     }  
   
     return(0);          if ((*psem).allocated != 0)
           {
               sys_free(psem);
           }
   
           return(0);
 #   endif  #   endif
 }  }
   
 int  int
 sem_unlink_SysV(const char *nom)  sem_unlink_SysV(char *nom)
 {  {
     // Détruit un sémaphore nommé créé par sem_open_SysV()      // Détruit un sémaphore nommé créé par sem_open_SysV()
 #   ifndef OS2  #   ifndef OS2 // IPCS_SYSV
           semctl(semget(ftok(nom, 1), 0, 0), 0, IPC_RMID);
     unsigned char       *nom_absolu;  
   
     if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)  
             + 1) * sizeof(unsigned char))) == NULL)  
     {  
         return(ENOMEM);  
     }  
   
     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);  
     }  
   
     free(nom_absolu);  
   
     return(0);          if (unlink(nom) == -1)
           {
               return(EACCES);
           }
   
           sys_free(nom);
           return(0);
 #   else  #   else
           return(0);
     return(0);  
   
 #   endif  #   endif
 }  }
   

Removed from v.1.28  
changed lines
  Added in v.1.89


CVSweb interface <joel.bertrand@systella.fr>