Diff for /rpl/src/interruptions.c between versions 1.31 and 1.35

version 1.31, 2010/08/17 14:15:20 version 1.35, 2010/08/25 09:06:49
Line 1726  deverrouillage_gestionnaire_signaux() Line 1726  deverrouillage_gestionnaire_signaux()
   
 #ifdef _BROKEN_SIGINFO  #ifdef _BROKEN_SIGINFO
   
   #define longueur_queue  256
   #define nombre_queues   13
   
 static int              *fifos;  static int              *fifos;
   static int              markov;
 static int              segment;  static int              segment;
 static int              segment_mutexes;  static sem_t            *semaphores[nombre_queues];
 static int              longueur_queue;  static sem_t            *semaphore_global;
 static int              nombre_queues;  
   
 static pthread_mutex_t  *mutexes;  
   
   #ifdef IPCS_SYSV
 static unsigned char    *chemin = NULL;  static unsigned char    *chemin = NULL;
   #endif
   
 unsigned char *  unsigned char *
 nom_segment(unsigned char *chemin, pid_t pid)  nom_segment(unsigned char *chemin, pid_t pid)
 {  {
     unsigned char               *fichier;      unsigned char               *fichier;
   
   #   ifdef IPCS_SYSV
     if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *      if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
             sizeof(unsigned char))) == NULL)              sizeof(unsigned char))) == NULL)
     {      {
Line 1748  nom_segment(unsigned char *chemin, pid_t Line 1752  nom_segment(unsigned char *chemin, pid_t
     }      }
   
     sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);      sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
   #   else
       if ((fichier = malloc((1 + 256 + 1) *
               sizeof(unsigned char))) == NULL)
       {
           return(NULL);
       }
   
       sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
   #   endif
   
     return(fichier);      return(fichier);
 }  }
   
 unsigned char *  unsigned char *
 nom_segment_mutexes(unsigned char *chemin, pid_t pid)  nom_semaphore(pid_t pid, int queue)
 {  {
     unsigned char               *fichier;      unsigned char               *fichier;
   
     if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *      if ((fichier = malloc((256 + 1) * sizeof(unsigned char))) == NULL)
             sizeof(unsigned char))) == NULL)  
     {      {
         return(NULL);          return(NULL);
     }      }
   
     sprintf(fichier, "%s/RPL-SIGMUTEXES-%d", chemin, (int) pid);      sprintf(fichier, "/RPL-SIGESMAPHORES-%d-%d", (int) pid, queue);
   
     return(fichier);      return(fichier);
 }  }
   
 int  inline int
 queue_de_signal(int signal)  queue_de_signal(int signal)
 {  {
     switch(signal)      switch(signal)
     {      {
         case SIGINT:          case SIGINT:
             BUG(1, uprintf("SIGINT is not queued as it does not "  
                     "come from program itself !\n"));  
             return(0);              return(0);
         case SIGTSTP:          case SIGTSTP:
             return(1);              return(1);
Line 1797  queue_de_signal(int signal) Line 1807  queue_de_signal(int signal)
             return(9);              return(9);
         case SIGFABORT:          case SIGFABORT:
             return(10);              return(10);
           case SIGSEGV:
               return(11);
           case SIGBUS:
               return(12);
     }      }
   
     return(-1);      return(-1);
Line 1805  queue_de_signal(int signal) Line 1819  queue_de_signal(int signal)
 void  void
 creation_fifos_signaux(struct_processus *s_etat_processus)  creation_fifos_signaux(struct_processus *s_etat_processus)
 {  {
     file                            *desc;      /*
        * Signaux utilisés
        * SIGINT, SIGTSTP, SIGCONT, SIGURG, SIGPIPE, SIGALRM, SIGFSTOP,
        * SIGSTART, SIGINJECT, SIGABORT, SIGFABORT
        */
   
     int                             i;      int                             i;
   
     key_t                           clef;      unsigned char                   *nom;
   
     pthread_mutexattr_t             attributs_mutex;  #   ifndef IPCS_SYSV // POSIX
   
     unsigned char                   *nom;      if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
               getpid())) == NULL)
       {
           (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
           return;
       }
   
     /*      if ((segment = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
      * Signaux utilisés              S_IRUSR | S_IWUSR)) == -1)
      * SIGINT, SIGTSTP, SIGCONT, SIGURG, SIGPIPE, SIGALRM, SIGFSTOP,      {
      * SIGSTART, SIGINJECT, SIGABORT, SIGFABORT          free(nom);
      */          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
           return;
       }
   
       if (ftruncate(segment, nombre_queues * ((2 * longueur_queue) + 4) *
               sizeof(int)) == -1)
       {
           free(nom);
           (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
           return;
       }
   
       fifos = mmap(NULL, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
               PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0);
       close(segment);
   
       if (((void *) fifos) == ((void *) -1))
       {
           if (shm_unlink(nom) == -1)
           {
               free(nom);
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           free(nom);
           (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
           return;
       }
   
       free(nom);
   
   #   else // SystemV
   
       file                            *desc;
   
       key_t                           clef;
   
     // Création d'un segment de données associé au PID du processus courant      // Création d'un segment de données associé au PID du processus courant
   
Line 1832  creation_fifos_signaux(struct_processus Line 1891  creation_fifos_signaux(struct_processus
         return;          return;
     }      }
   
     /*  
      * Structure d'une queue  
      * 0 : pointeur en lecture sur le premier emplacement libre (int)  
      * 1 : pointeur en écriture sur le premier emplacement à lire (int)  
      * 2 : longueur de la queue (int)  
      * 3 : éléments restants (int)  
      * 4 à 4 + (2) : queue (int)  
      * 5 : mutex  
      */  
   
     nombre_queues = 11;  
     longueur_queue = 256;  
   
     if ((desc = fopen(nom, "w")) == NULL)      if ((desc = fopen(nom, "w")) == NULL)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;          (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
Line 1862  creation_fifos_signaux(struct_processus Line 1908  creation_fifos_signaux(struct_processus
     free(nom);      free(nom);
   
     if ((segment = shmget(clef,      if ((segment = shmget(clef,
             nombre_queues * (longueur_queue + 4) * sizeof(int),              nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
             IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)              IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
Line 1873  creation_fifos_signaux(struct_processus Line 1919  creation_fifos_signaux(struct_processus
   
     if (((void *) fifos) == ((void *) -1))      if (((void *) fifos) == ((void *) -1))
     {      {
           if (shmctl(segment, IPC_RMID, 0) == -1)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;          return;
     }      }
   
   #   endif
   
       /*
        * Structure d'une queue
        * 0 : pointeur en lecture sur le premier emplacement libre (int)
        * 1 : pointeur en écriture sur le premier emplacement à lire (int)
        * 2 : longueur de la queue (int)
        * 3 : éléments restants (int)
        * 4 à 4 + (2) : queue (int)
        * 4 + (2) + 1 ) 4 + 2 * (2) : horodatage en centième de secondes.
        */
   
     for(i = 0; i < nombre_queues; i++)      for(i = 0; i < nombre_queues; i++)
     {      {
         fifos[(i * (longueur_queue + 4))] = 0;          fifos[(i * (longueur_queue + 4))] = 0;
Line 1885  creation_fifos_signaux(struct_processus Line 1949  creation_fifos_signaux(struct_processus
         fifos[(i * (longueur_queue + 4)) + 3] = longueur_queue;          fifos[(i * (longueur_queue + 4)) + 3] = longueur_queue;
     }      }
   
     if ((nom = nom_segment_mutexes((*s_etat_processus)      // Création des sémaphores : un sémaphore par signal et par queue
             .chemin_fichiers_temporaires, getpid())) == NULL)      // plus un sémaphore global pour tous les threads.
     {  
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;  
         return;  
     }  
   
     if ((desc = fopen(nom, "w")) == NULL)      for(i = 0; i < nombre_queues; i++)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;          if ((nom = nom_semaphore(getpid(), i)) == NULL)
         return;          {
     }              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
     fclose(desc);          // Le sémaphore est créé en écrasant si nécessaire un sémaphore
           // préexistant. Comme le nom du sémaphore contient l'identifiant du
           // processus, il est anormal d'avoir un sémaphore de même nom
           // préexistant.
   
     if ((clef = ftok(nom, 1)) == -1)          if ((semaphores[i] = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR,
     {                  1)) == SEM_FAILED)
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          {
         return;              (*s_etat_processus).erreur_systeme = d_es_semaphore;
               return;
           }
   
           free(nom);
     }      }
   
     free(nom);  
   
     if ((segment_mutexes = shmget(clef,      if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
             nombre_queues * sizeof(pthread_mutex_t),  
             IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)  
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;          return;
     }      }
   
     mutexes = shmat(segment_mutexes, NULL, 0);      if ((semaphore_global = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR,
               1)) == SEM_FAILED)
     if (((void *) mutexes) == ((void *) -1))  
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_semaphore;
         return;          return;
     }      }
   
     /*      free(nom);
      * Création et initialisation d'un mutex par queue. Ce mutex n'est pas  
      * dans le premier segment parce qu'il peut y avoir des problèmes  
      * d'alignements sur certaines architectures.  
      */  
   
     pthread_mutexattr_init(&attributs_mutex);  
     pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE);  
   
     for(i = 0; i < nombre_queues; i++)      markov = 0;
     {  
         pthread_mutex_init(&(mutexes[i]), &attributs_mutex);  
     }  
   
     pthread_mutexattr_destroy(&attributs_mutex);  
     return;      return;
 }  }
   
 void  void
 liberation_fifos_signaux(struct_processus *s_etat_processus)  liberation_fifos_signaux(struct_processus *s_etat_processus)
 {  {
       int                 i;
   
   #   ifdef IPCS_SYSV // SystemV
   
     if (shmdt(fifos) == -1)      if (shmdt(fifos) == -1)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;          return;
     }      }
   
     if (shmdt(mutexes) == -1)  #   else // POSIX
   
       if (munmap(fifos, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int))
               != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;          return;
     }      }
   
   #   endif
   
       for(i = 0; i < nombre_queues; i++)
       {
           if (sem_close(semaphores[i]) != 0)
           {
               (*s_etat_processus).erreur_systeme = d_es_semaphore;
               return;
           }
       }
   
       if (sem_close(semaphore_global) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_semaphore;
           return;
       }
   
     return;      return;
 }  }
   
Line 1967  destruction_fifos_signaux(struct_process Line 2045  destruction_fifos_signaux(struct_process
   
     unsigned char       *nom;      unsigned char       *nom;
   
   #   ifdef IPCS_SYSV // SystemV
   
     if (shmdt(fifos) == -1)      if (shmdt(fifos) == -1)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
Line 1979  destruction_fifos_signaux(struct_process Line 2059  destruction_fifos_signaux(struct_process
         return;          return;
     }      }
   
     for(i = 0; i < nombre_queues; i++)      if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
               getpid())) == NULL)
     {      {
         pthread_mutex_destroy(&(mutexes[i]));          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
           return;
     }      }
   
     if (shmdt(mutexes) == -1)      unlink(nom);
       free(nom);
   
   #   else // POSIX
   
       if (munmap(fifos, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int))
               != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;          return;
     }      }
   
     if (shmctl(segment_mutexes, IPC_RMID, 0) == -1)      if ((nom = nom_segment(NULL, getpid())) == NULL)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;          return;
     }      }
   
     if ((nom = nom_segment_mutexes((*s_etat_processus)      if (shm_unlink(nom) != 0)
             .chemin_fichiers_temporaires, getpid())) == NULL)  
     {      {
           free(nom);
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;          return;
     }      }
   
     unlink(nom);  
     free(nom);      free(nom);
   
     if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,  #   endif
             getpid())) == NULL)  
       for(i = 0; i < nombre_queues; i++)
       {
           if ((nom = nom_semaphore(getpid(), i)) == NULL)
           {
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           if (sem_unlink(nom) != 0)
           {
               (*s_etat_processus).erreur_systeme = d_es_semaphore;
               return;
           }
   
           free(nom);
       }
   
       if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;          return;
     }      }
   
     unlink(nom);      if (sem_unlink(nom) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_semaphore;
           return;
       }
   
     free(nom);      free(nom);
   
     return;      return;
 }  }
   
   inline int
   horodatage()
   {
       int             ts;
   
       struct timeval  tv;
   
       gettimeofday(&tv, NULL);
       ts = (int) ((tv.tv_sec * 100) + (tv.tv_usec / 10000));
   
       return(ts);
   }
   
 int  int
 queue_in(pid_t pid, int signal)  queue_in(pid_t pid, int signal)
 {  {
       int             queue;
     int             *base;      int             *base;
     int             *buffer;      int             *buffer;
     int             *projection_fifos;      int             horodatage_initial;
     int             queue;  
     int             identifiant;      int             identifiant;
       int             *projection_fifos;
   
     key_t           clef;      sem_t           *semaphore;
   
     pthread_mutex_t *projection_mutexes;      queue = queue_de_signal(signal);
   
     unsigned char   *nom;      unsigned char   *nom;
   
     queue = queue_de_signal(signal);  #   ifndef IPCS_SYSV
   
     // Ouverture des projections      // Ouverture des projections
   
     if ((nom = nom_segment(chemin, pid)) == NULL)      if ((nom = nom_segment(NULL, pid)) == NULL)
     {      {
         return(-1);          return(-1);
     }      }
   
     if ((clef = ftok(nom, 1)) == -1)      // Dans le cas de SIGSTART, premier signal envoyé à un processus fils,
       // il convient d'attendre que le fichier support soit effectivement
       // accessible. Dans tous les autres cas, ce fichier doit exister. S'il
       // n'existe plus, le processus associé n'existe plus.
   
       if (signal == SIGSTART)
       {
           horodatage_initial = horodatage();
   
           while((identifiant = shm_open(nom, O_RDWR, S_IRUSR | S_IWUSR)) == -1)
           {
               if (abs(horodatage_initial - horodatage()) > 500)
               {
                   return(-1);
               }
           }
       }
       else
       {
           if ((identifiant = shm_open(nom, O_RDWR, S_IRUSR | S_IWUSR)) == -1)
           {
               return(-1);
           }
       }
   
       projection_fifos = mmap(NULL, nombre_queues * ((2 * longueur_queue) + 4)
               * sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, identifiant, 0);
       close(identifiant);
   
       if (((void *) projection_fifos) == ((void *) -1))
     {      {
         free(nom);  
         return(-1);          return(-1);
     }      }
   
     free(nom);  #   else // Traitement à l'aide d'IPCS SystemV
   
     while((identifiant = shmget(clef,      key_t           clef;
             nombre_queues * (longueur_queue + 4) * sizeof(int),  
             S_IRUSR | S_IWUSR)) == -1);  
   
     projection_fifos = shmat(identifiant, NULL, 0);      struct stat     s_stat;
   
       // Ouverture des projections
   
     if ((nom = nom_segment_mutexes(chemin, pid)) == NULL)      if ((nom = nom_segment(chemin, pid)) == NULL)
     {      {
         return(-1);          return(-1);
     }      }
   
       // Dans le cas de SIGSTART, premier signal envoyé à un processus fils,
       // il convient d'attendre que le fichier support soit effectivement
       // accessible. Dans tous les autres cas, ce fichier doit exister. S'il
       // n'existe plus, le processus associé n'existe plus.
   
       if (signal == SIGSTART)
       {
           // On attend que le fichier sois présent
   
           horodatage_initial = horodatage();
   
           while(stat(nom, &s_stat) != 0)
           {
               if (abs(horodatage_initial - horodatage()) > 500)
               {
                   return(-1);
               }
           }
       }
   
     if ((clef = ftok(nom, 1)) == -1)      if ((clef = ftok(nom, 1)) == -1)
     {      {
         free(nom);  
         return(-1);          return(-1);
     }      }
   
     free(nom);      free(nom);
   
     while((identifiant = shmget(clef,      if (signal == SIGSTART)
             nombre_queues * sizeof(pthread_mutex_t),      {
             S_IRUSR | S_IWUSR)) == -1);          while((identifiant = shmget(clef,
                   nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
                   S_IRUSR | S_IWUSR)) == -1);
       }
       else
       {
           if ((identifiant = shmget(clef,
                   nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
                   S_IRUSR | S_IWUSR)) == -1)
           {
               return(-1);
           }
       }
   
       projection_fifos = shmat(identifiant, NULL, 0);
   
       if (((void *) projection_fifos) == ((void *) -1))
       {
           return(-1);
       }
   
     projection_mutexes = shmat(identifiant, NULL, 0);  #   endif
   
     if (pthread_mutex_lock(&(projection_mutexes[queue])) != 0)      if ((nom = nom_semaphore(pid, queue)) == NULL)
     {      {
   #       ifdef IPCS_SYSV
           shmdt(projection_fifos);
   #       else
           munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
                   * sizeof(int));
   #       endif
         return(-1);          return(-1);
     }      }
   
       while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
       free(nom);
   
       while(sem_wait(semaphore) != 0)
       {
           if (errno != EINTR)
           {
   #           ifdef IPCS_SYSV
               shmdt(projection_fifos);
   #           else
               munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
                       * sizeof(int));
   #           endif
               return(-1);
           }
       }
   
     base = &(projection_fifos[(longueur_queue + 4) * queue]);      base = &(projection_fifos[(longueur_queue + 4) * queue]);
     buffer = &(base[4]);      buffer = &(base[4]);
   
     // base[1] contient le prochain élément à écrire      // base[3] contient le nombre d'éléments restants
     buffer[base[1]++] = (int) pid;  
     base[1] %= base[2];  
   
     // base[3] contient le nombre d'éléments non lus  
     if (base[3] <= 0)      if (base[3] <= 0)
     {      {
         pthread_mutex_unlock(&(projection_mutexes[queue]));          sem_post(semaphore);
         shmdt(projection_mutexes);          sem_close(semaphore);
   #       ifdef IPCS_SYSV
         shmdt(projection_fifos);          shmdt(projection_fifos);
   #       else
           munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
                   * sizeof(int));
   #       endif
         return(-1);          return(-1);
     }      }
   
     base[3]--;      base[3]--;
   
     if (pthread_mutex_unlock(&(projection_mutexes[queue])) != 0)      // base[1] contient le prochain élément à écrire
   
       buffer[base[1] + (nombre_queues * base[2])] = horodatage();
       buffer[base[1]++] = (int) pid;
       base[1] %= base[2];
   
       if (sem_post(semaphore) != 0)
     {      {
         shmdt(projection_mutexes);  #       ifdef IPCS_SYSV
         shmdt(projection_fifos);          shmdt(projection_fifos);
   #       else
           munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
                   * sizeof(int));
   #       endif
           sem_close(semaphore);
         return(-1);          return(-1);
     }      }
   
       sem_close(semaphore);
   
     // Fermeture des projections      // Fermeture des projections
     shmdt(projection_mutexes);  #   ifdef IPCS_SYSV
     shmdt(projection_fifos);      shmdt(projection_fifos);
   #   else
       munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
               * sizeof(int));
   #   endif
   
     return(0);      return(0);
 }  }
   
   inline int
   chaine_markov(int markov, int delta)
   {
       double      memoire = 0.9;
       int         valeur;
   
       valeur = (int) ((memoire * markov) + ((1 - memoire) * delta));
       valeur = (valeur < 10) ? 10 : valeur;
   
       return(valeur);
   }
   
 pid_t  pid_t
 origine_signal(int signal)  origine_signal(int signal)
 {  {
       logical1        drapeau;
   
     int             *base;      int             *base;
     int             *buffer;      int             *buffer;
       int             delta;
     int             pid;      int             pid;
     int             queue;      int             queue;
   
Line 2125  origine_signal(int signal) Line 2373  origine_signal(int signal)
     BUG(queue == -1, uprintf("[%d] Unknown signal %d in this context\n",      BUG(queue == -1, uprintf("[%d] Unknown signal %d in this context\n",
             (int) getpid(), signal));              (int) getpid(), signal));
   
     if (pthread_mutex_lock(&(mutexes[queue])) != 0)      while(sem_wait(semaphores[queue]) != 0)
     {      {
         return(-1);          if (errno != EINTR)
           {
               return(-1);
           }
     }      }
   
       // On retire les interruptions anciennes qui ont été ratées sauf s'il
       // s'agit de la dernière dans la queue.
   
     base = &(fifos[(longueur_queue + 4) * queue]);      base = &(fifos[(longueur_queue + 4) * queue]);
     buffer = &(base[4]);      buffer = &(base[4]);
     pid = buffer[base[0]++];  
     base[0] %= base[2];  
     base[3]++;  
   
     if (base[3] > base[2])      if (base[3] == (base[2] - 1))
     {      {
         pthread_mutex_unlock(&(mutexes[queue]));          delta = abs(horodatage() -
         return(-1);                   buffer[base[0] + (nombre_queues * base[2])]);
           // Une seule interruption dans la queue.
           pid = buffer[base[0]++];
           base[0] %= base[2];
           base[3]++;
   
           markov = chaine_markov(markov, delta);
       }
       else if (base[3] >= base[2])
       {
           // Aucune interruption n'est dans la queue.
           // On a retiré trop d'interruptions de la queue.
   
           // (base[3] - base[2]) + 1 : nombre d'interruptions manquantes
           // base[0] - 1             : dernière interruption lue
           pid = buffer[((((base[0] + base[2] - 1) % base[2])
                   - ((base[3] - base[2]) + 1)) + base[2]) % base[2]];
       }
       else
       {
           // Plusieurs interruptions à distribuer.
           drapeau = d_vrai;
   
           do
           {
               delta = abs(horodatage() -
                        buffer[base[0] + (nombre_queues * base[2])]);
               pid = buffer[base[0]++];
               base[0] %= base[2];
               base[3]++;
   
               if ((delta > (2 * markov)) && (base[3] < base[2]))
               {
                   drapeau = d_vrai;
               }
               else
               {
                   drapeau = d_faux;
               }
           } while(drapeau == d_vrai);
   
           markov = chaine_markov(markov, delta);
     }      }
     if (pthread_mutex_unlock(&(mutexes[queue])) != 0)  
       if (sem_post(semaphores[queue]) != 0)
     {      {
         perror("unlock");  
         return(-1);          return(-1);
     }      }
   
Line 2163  interruption1(SIGHANDLER_ARGS) Line 2455  interruption1(SIGHANDLER_ARGS)
   
     volatile sig_atomic_t   exclusion = 0;      volatile sig_atomic_t   exclusion = 0;
   
       verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
     if (signal == SIGINT)      if (signal == SIGINT)
     {      {
Line 2179  interruption1(SIGHANDLER_ARGS) Line 2473  interruption1(SIGHANDLER_ARGS)
     pid = (*siginfo).si_pid;      pid = (*siginfo).si_pid;
 #   endif  #   endif
   
     verrouillage_gestionnaire_signaux();  
   
     switch(signal)      switch(signal)
     {      {
         case SIGALRM :          case SIGALRM :
Line 2320  interruption2(SIGHANDLER_ARGS) Line 2612  interruption2(SIGHANDLER_ARGS)
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
     pid = origine_signal(signal);      pid = origine_signal(signal);
 #   else  #   else
     pid = (*siginfo).si_pid;      pid = (*siginfo).si_pid;
 #   endif  #   endif
   
     verrouillage_gestionnaire_signaux();  
   
 #   ifndef _BROKEN_SIGINFO  #   ifndef _BROKEN_SIGINFO
     if (siginfo == NULL)      if (siginfo == NULL)
     {      {
Line 2404  interruption3(SIGHANDLER_ARGS) Line 2696  interruption3(SIGHANDLER_ARGS)
   
     static int              compteur = 0;      static int              compteur = 0;
   
       verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
     pid = origine_signal(signal);      pid = origine_signal(signal);
 #   else  #   else
     pid = (*siginfo).si_pid;      pid = (*siginfo).si_pid;
 #   endif  #   endif
   
     verrouillage_gestionnaire_signaux();  
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)      if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
     {      {
         deverrouillage_gestionnaire_signaux();          deverrouillage_gestionnaire_signaux();
Line 2470  interruption4(SIGHANDLER_ARGS) Line 2762  interruption4(SIGHANDLER_ARGS)
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
     pid = origine_signal(signal);      pid = origine_signal(signal);
 #   else  #   else
     pid = (*siginfo).si_pid;      pid = (*siginfo).si_pid;
 #   endif  #   endif
   
     verrouillage_gestionnaire_signaux();  
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)      if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
     {      {
         deverrouillage_gestionnaire_signaux();          deverrouillage_gestionnaire_signaux();
Line 2508  interruption5(SIGHANDLER_ARGS) Line 2800  interruption5(SIGHANDLER_ARGS)
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
     pid = origine_signal(signal);      pid = origine_signal(signal);
 #   else  #   else
     pid = (*siginfo).si_pid;      pid = (*siginfo).si_pid;
 #   endif  #   endif
   
     verrouillage_gestionnaire_signaux();  
   
     if (pid == getpid())      if (pid == getpid())
     {      {
         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))          if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
Line 2578  interruption6(SIGHANDLER_ARGS) Line 2870  interruption6(SIGHANDLER_ARGS)
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
     pid = origine_signal(signal);      pid = origine_signal(signal);
 #   else  #   else
     pid = (*siginfo).si_pid;      pid = (*siginfo).si_pid;
 #   endif  #   endif
   
     verrouillage_gestionnaire_signaux();  
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)      if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
     {      {
         deverrouillage_gestionnaire_signaux();          deverrouillage_gestionnaire_signaux();
Line 2610  interruption7(SIGHANDLER_ARGS) Line 2902  interruption7(SIGHANDLER_ARGS)
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
     pid = origine_signal(signal);      pid = origine_signal(signal);
 #   else  #   else
     pid = (*siginfo).si_pid;      pid = (*siginfo).si_pid;
 #   endif  #   endif
   
     verrouillage_gestionnaire_signaux();  
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)      if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
     {      {
         deverrouillage_gestionnaire_signaux();          deverrouillage_gestionnaire_signaux();
Line 2647  interruption8(SIGHANDLER_ARGS) Line 2939  interruption8(SIGHANDLER_ARGS)
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
     pid = origine_signal(signal);      pid = origine_signal(signal);
 #   else  #   else
     pid = (*siginfo).si_pid;      pid = (*siginfo).si_pid;
 #   endif  #   endif
   
     verrouillage_gestionnaire_signaux();  
   
     if (pid == getpid())      if (pid == getpid())
     {      {
         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))          if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
Line 2697  interruption9(SIGHANDLER_ARGS) Line 2989  interruption9(SIGHANDLER_ARGS)
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
     pid = origine_signal(signal);      pid = origine_signal(signal);
 #   else  #   else
     pid = (*siginfo).si_pid;      pid = (*siginfo).si_pid;
 #   endif  #   endif
   
     verrouillage_gestionnaire_signaux();  
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)      if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
     {      {
         deverrouillage_gestionnaire_signaux();          deverrouillage_gestionnaire_signaux();
Line 2718  interruption9(SIGHANDLER_ARGS) Line 3010  interruption9(SIGHANDLER_ARGS)
         fflush(stdout);          fflush(stdout);
     }      }
   
     deverrouillage_gestionnaire_signaux();  
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
     if (queue_in(getpid(), signal) != 0)      if (queue_in(getpid(), signal) != 0)
     {      {
         return;          return;
     }      }
   
       deverrouillage_gestionnaire_signaux();
     interruption11(signal);      interruption11(signal);
 #   else  #   else
       deverrouillage_gestionnaire_signaux();
     interruption11(signal, siginfo, context);      interruption11(signal, siginfo, context);
 #   endif  #   endif
     return;      return;
Line 2744  interruption10(SIGHANDLER_ARGS) Line 3036  interruption10(SIGHANDLER_ARGS)
   
     unsigned char           nom[8 + 64 + 1];      unsigned char           nom[8 + 64 + 1];
   
       verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
     pid = origine_signal(signal);      pid = origine_signal(signal);
 #   else  #   else
     pid = (*siginfo).si_pid;      pid = (*siginfo).si_pid;
 #   endif  #   endif
   
     verrouillage_gestionnaire_signaux();  
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)      if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
     {      {
         deverrouillage_gestionnaire_signaux();          deverrouillage_gestionnaire_signaux();
Line 2791  interruption11(SIGHANDLER_ARGS) Line 3083  interruption11(SIGHANDLER_ARGS)
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
     pid = origine_signal(signal);      pid = origine_signal(signal);
 #   else  #   else
     pid = (*siginfo).si_pid;      pid = (*siginfo).si_pid;
 #   endif  #   endif
   
     verrouillage_gestionnaire_signaux();  
   
     if (pid == getpid())      if (pid == getpid())
     {      {
         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))          if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
Line 2883  traitement_exceptions_gsl(const char *re Line 3175  traitement_exceptions_gsl(const char *re
 #undef pthread_kill  #undef pthread_kill
   
 int  int
 rpl_kill(pid_t pid, int signal)  kill_broken_siginfo(pid_t pid, int signal)
 {  {
       int                 ios;
   
       sem_t               *semaphore;
   
       unsigned char       *nom;
   
     /*      /*
      * Lorsqu'on veut interrompre le processus pid, on ouvre le segment       * Lorsqu'on veut interrompre le processus pid, on ouvre le segment
      * correspondant au processus en question et ou ajoute le pid dans la       * correspondant au processus en question et ou ajoute le pid dans la
      * queue.       * queue.
        *
        * Le sémaphore global à tous les threads d'un même processus sert
        * à garantir que les signaux seront traités dans l'ordre de ce qui est
        * effectivement mis dans la queue.
      */       */
   
       // Sémaphore acquis
   
       if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
       {
           return(-1);
       }
   
       while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
       free(nom);
   
       while(sem_wait(semaphore) != 0)
       {
           if (errno != EINTR)
           {
               return(-1);
           }
       }
   
     if ((signal != 0) && (signal != SIGINT))      if ((signal != 0) && (signal != SIGINT))
     {      {
         if (queue_in(pid, signal) != 0)          if (queue_in(pid, signal) != 0)
         {          {
               sem_post(semaphore);
               sem_close(semaphore);
             return(-1);              return(-1);
         }          }
     }      }
   
     return(kill(pid, signal));      ios = kill(pid, signal);
   
       // Sémaphore relâché
   
       sem_post(semaphore);
       sem_close(semaphore);
   
       return(ios);
 }  }
   
 int  int
 rpl_pthread_kill(pthread_t tid, int signal)  pthread_kill_broken_siginfo(pthread_t tid, int signal)
 {  {
       int                 ios;
   
       sem_t               *semaphore;
   
       unsigned char       *nom;
   
       if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
       {
           return(-1);
       }
   
       while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
       free(nom);
   
       while(sem_wait(semaphore) != 0)
       {
           if (errno != EINTR)
           {
               return(-1);
           }
       }
   
     if ((signal != 0) && (signal != SIGINT))      if ((signal != 0) && (signal != SIGINT))
     {      {
         if (queue_in(getpid(), signal) != 0)          if (queue_in(getpid(), signal) != 0)
         {          {
               sem_post(semaphore);
               sem_close(semaphore);
             return(-1);              return(-1);
         }          }
     }      }
   
     return(pthread_kill(tid, signal));      ios = pthread_kill(tid, signal);
   
       sem_post(semaphore);
       sem_close(semaphore);
   
       return(ios);
 }  }
   
 #endif  #endif

Removed from v.1.31  
changed lines
  Added in v.1.35


CVSweb interface <joel.bertrand@systella.fr>