Diff for /rpl/src/semaphores.c between versions 1.26 and 1.36

version 1.26, 2011/07/22 07:38:41 version 1.36, 2011/09/20 16:57:50
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.1    RPL/2 (R) version 4.1.3
   Copyright (C) 1989-2011 Dr. BERTRAND Joël    Copyright (C) 1989-2011 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
Line 24 Line 24
   
 #ifdef SEMAPHORES_NOMMES  #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 = malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL)
       {
           return(NULL);
       }
   
       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);
   }
   
   
 /*  /*
 ================================================================================  ================================================================================
   Fonctions d'émulation de sémaphores anonymes    Fonctions d'émulation de sémaphores anonymes
Line 37 Line 72
 */  */
   
 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;
   
       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);
   
       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)
       {
           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, 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);
       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);
       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);
       free(chemin);
   
       return(erreur);
 }  }
   
   
 #undef sem_post  #undef sem_post
 #undef sem_wait  #undef sem_wait
 #undef sem_trywait  #undef sem_trywait
Line 62  int Line 180  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);
         }          }
   
           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);
 }  }
   
Line 121  sem_getvalue2(sem_t *semaphore, int *val Line 257  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 269  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;
   
           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).tid = pthread_self();
               (*semaphore).alloue = 0;
           }
           else
           {
               // Sémaphore partagé entre plusieurs processus
               if (((*semaphore).path = malloc((strlen(racine_segment)
                       + 2 + 256 + 1) * sizeof(unsigned char))) == NULL)
               {
                   return(-1);
               }
   
     union semun     argument;              sprintf((*semaphore).path, "%s/RPL-SEMAPHORE-%d-%llX-%d",
                       racine_segment, (int) getpid(), pthread_self(), shared);
   
     if (shared != 0)              if ((desc = open((*semaphore).path, O_RDWR | O_CREAT | O_EXCL,
     {                      S_IRUSR | S_IWUSR)) == -1)
         errno = ENOSYS;              {
         return(-1);                  free((*semaphore).path);
     }                  return(-1);
               }
   
     (*semaphore).sem = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL |              (*semaphore).pid = getpid();
             S_IRUSR | S_IWUSR);              (*semaphore).tid = pthread_slef();
     (*semaphore).path = NULL;              clef = ftok((*semaphore).path, 1);
     (*semaphore).pid = getpid();              close(desc);
   
     if ((*semaphore).sem == -1)              if (clef == -1)
     {              {
         errno = EINVAL;                  free((*semaphore).path);
         return(-1);                  return(-1);
     }              }
   
     argument.val = valeur;              (*semaphore).alloue = 0;
     ios = semctl((*semaphore).sem, 0, SETVAL, argument);              (*semaphore).sem = semget(clef, 1, IPC_CREAT | IPC_EXCL |
                       S_IRUSR | S_IWUSR);
           }
   
     return(ios);          if ((*semaphore).sem == -1)
           {
               errno = EINVAL;
               return(-1);
           }
   
 #   else          argument.val = valeur;
           ios = semctl((*semaphore).sem, 0, SETVAL, argument);
   
           return(ios);
   #   else // OS/2
   
     sem_t           *psem;      sem_t           *psem;
   
Line 219  int Line 391  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)  #   ifndef OS2 // IPCS_SYSV
     {          if ((*semaphore).path != NULL)
         return(EINVAL);          {
     }              return(EINVAL);
           }
     if ((*semaphore).pid != getpid())  
     {  
         return(0);  
     }  
   
     if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)          if ((*semaphore).pid != getpid())
     {          {
         return(EINVAL);              return(0);
     }          }
   
     return(0);          if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)
           {
               return(EINVAL);
           }
   
 #   else          return(0);
   #   else // OS/2
   
     sem_t       *psem;      sem_t       *psem;
   
Line 287  sem_destroy_SysV(sem_t *semaphore) Line 458  sem_destroy_SysV(sem_t *semaphore)
 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;          commande.sem_num = 0;
           commande.sem_op = -1;
           commande.sem_flg = 0;
   
     commande.sem_num = 0;          while(semop((*semaphore).sem, &commande, 1) == -1)
     commande.sem_op = -1;  
     commande.sem_flg = 0;  
   
     while(semop((*semaphore).sem, &commande, 1) == -1)  
     {  
         if (errno != EINTR)  
         {          {
             errno = EINVAL;              if (errno != EINTR)
             return(-1);              {
                   errno = EINVAL;
                   return(-1);
               }
         }          }
     }  
   
     return(0);  
   
 #   else          return(0);
   #   else // OS/2
   
     sem_t       *psem;      sem_t       *psem;
   
Line 345  sem_wait_SysV(sem_t *semaphore) Line 514  sem_wait_SysV(sem_t *semaphore)
 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)          while(semop((*semaphore).sem, &commande, 1) == -1)
     {  
         if (errno != EINTR)  
         {          {
             errno = EINVAL;              if (errno != EINTR)
             return(-1);              {
                   errno = EINVAL;
                   return(-1);
               }
         }          }
     }  
   
     return(0);  
   
 #   else          return(0);
   #   else // OS/2
   
     int         ios;      int         ios;
   
Line 405  sem_trywait_SysV(sem_t *semaphore) Line 572  sem_trywait_SysV(sem_t *semaphore)
 int  int
 sem_post_SysV(sem_t *semaphore)  sem_post_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 = 0;          commande.sem_flg = 0;
   
     while(semop((*semaphore).sem, &commande, 1) == -1)          while(semop((*semaphore).sem, &commande, 1) == -1)
     {  
         if (errno != EINTR)  
         {          {
             errno = EINVAL;              if (errno != EINTR)
             return(-1);              {
                   errno = EINVAL;
                   return(-1);
               }
         }          }
     }  
   
     return(0);  
   
 #   else          return(0);
   #   else // OS/2
   
     sem_t               *psem;      sem_t               *psem;
   
Line 448  sem_post_SysV(sem_t *semaphore) Line 613  sem_post_SysV(sem_t *semaphore)
 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;
Line 489  sem_t Line 652  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;
 #   endif  #   endif
   
     unsigned char       *nom_absolu;      unsigned char       *nom_absolu;
Line 503  sem_t Line 666  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 = 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 = 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 = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1)      if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1)
Line 581  sem_t Line 746  sem_t
     {      {
         // 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)
               {   
                   free(semaphore);
                   free(nom_absolu);
   
                   return(SEM_FAILED);
               }
   #       else // OS/2
         if ((psem = malloc(sizeof(sem_t))) == NULL)          if ((psem = malloc(sizeof(sem_t))) == NULL)
         {          {
             free(nom_absolu);              free(nom_absolu);
Line 683  sem_t Line 845  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);                  free(semaphore);
             free(nom_absolu);                  free(nom_absolu);
   
             return(SEM_FAILED);                  return(SEM_FAILED);
         }              }
   
         fclose(desc);              if ((clef = ftok(nom_absolu, 1)) == -1)
               {
                   close(desc);
                   free(semaphore);
                   free(nom_absolu);
   
         if ((clef = ftok(nom_absolu, 1)) == -1)                  return(SEM_FAILED);
         {              }
             free(semaphore);  
             free(nom_absolu);  
   
             return(SEM_FAILED);              close(desc);
         }  
   
         (*semaphore).sem = semget(clef, 1,              (*semaphore).sem = semget(clef, 1,
                 (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) |                      (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) |
                 (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) |                      (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) |
                 (int) mode);                      (int) mode);
         (*semaphore).path = nom_absolu;              (*semaphore).path = nom_absolu;
         (*semaphore).pid = getpid();              (*semaphore).pid = getpid();
   
               if ((*semaphore).sem == -1)
               {   
                   free(semaphore);
                   free(nom_absolu);
   
         if ((*semaphore).sem == -1)                  return(SEM_FAILED);
         {                 }
             free(semaphore);  
             free(nom_absolu);  
   
             return(SEM_FAILED);  
         }  
   
         argument.val = valeur;  
         semctl((*semaphore).sem, 0, SETVAL, argument);  
   
 #       else              argument.val = valeur;
               semctl((*semaphore).sem, 0, SETVAL, argument);
   #       else // OS/2
   
         if ((psem = malloc(sizeof(sem_t))) == NULL)          if ((psem = malloc(sizeof(sem_t))) == NULL)
         {          {
Line 787  int Line 949  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)          {
     {              free((*semaphore).path);
         free((*semaphore).path);          }
     }  
   
     free(semaphore);          if ((*semaphore).alloue == -1)
     return(0);          {
               free(semaphore);
           }
   
           return(0);
 #   else  #   else
   
     sem_t       *psem;      sem_t       *psem;
Line 842  int Line 1006  int
 sem_unlink_SysV(const char *nom)  sem_unlink_SysV(const 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_absolu, 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);          if (unlink(nom_absolu) == -1)
     semctl(semget(ftok(nom_absolu, 1), 0, 0), 0, IPC_RMID);          {
               free(nom_absolu);
               return(EACCES);
           }
   
     if (unlink(nom_absolu) == -1)  
     {  
         free(nom_absolu);          free(nom_absolu);
         return(EACCES);          return(0);
     }  
   
     free(nom_absolu);  
   
     return(0);  
   
 #   else  #   else
   
     return(0);      return(0);

Removed from v.1.26  
changed lines
  Added in v.1.36


CVSweb interface <joel.bertrand@systella.fr>