Diff for /rpl/src/interruptions.c between versions 1.154 and 1.208

version 1.154, 2015/01/29 09:33:41 version 1.208, 2022/09/07 13:40:41
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.20    RPL/2 (R) version 4.1.34
   Copyright (C) 1989-2015 Dr. BERTRAND Joël    Copyright (C) 1989-2021 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
   
Line 65  thread_surveillance_signaux(void *argume Line 65  thread_surveillance_signaux(void *argume
 {  {
     // Cette fonction est lancée dans un thread créé par processus pour      // Cette fonction est lancée dans un thread créé par processus pour
     // gérer le cas des appels système qui seraient bloqués lors de l'arrivée du      // gérer le cas des appels système qui seraient bloqués lors de l'arrivée du
     // signal SIGALRM. Les processus externes n'envoient plus un signal au      // signal SIGUSR2. Les processus externes n'envoient plus un signal au
     // processus ou au thread à signaler mais positionnent les informations      // processus ou au thread à signaler mais positionnent les informations
     // nécessaires dans la queue des signaux et incrémentent le sémaphore.      // nécessaires dans la queue des signaux et incrémentent le sémaphore.
     // Le sémaphore est décrémenté lorsque le signal est effectivement traité.      // Le sémaphore est décrémenté lorsque le signal est effectivement traité.
Line 92  thread_surveillance_signaux(void *argume Line 92  thread_surveillance_signaux(void *argume
   
         if (sem_wait(semaphore_signalisation) == 0)          if (sem_wait(semaphore_signalisation) == 0)
         {          {
             if (sem_wait(semaphore_arret_signalisation) != 0)              while(sem_wait(semaphore_arret_signalisation) != 0)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  if (errno != EINTR)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                   }
             }              }
   
             if ((*s_queue_signaux).requete_arret == d_vrai)              if ((*s_queue_signaux).requete_arret == d_vrai)
Line 105  thread_surveillance_signaux(void *argume Line 108  thread_surveillance_signaux(void *argume
                 break;                  break;
             }              }
   
             sem_post(semaphore_arret_signalisation);  
             sem_post(semaphore_signalisation);              sem_post(semaphore_signalisation);
   
             nombre_signaux_envoyes = 0;              nombre_signaux_envoyes = 0;
             sched_yield();  
   
             // Dans un premier temps, on verrouille la queue des signaux              // Dans un premier temps, on verrouille la queue des signaux
             // affectée au processus courant pour vérifier s'il y a quelque              // affectée au processus courant pour vérifier s'il y a quelque
             // chose à traiter.              // chose à traiter.
   
             sem_wait(semaphore_queue_signaux);              while(sem_wait(semaphore_queue_signaux) != 0)
               {
                   if (errno != EINTR)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                   }
               }
   
             if ((*s_queue_signaux).pointeur_lecture !=              if ((*s_queue_signaux).pointeur_lecture !=
                     (*s_queue_signaux).pointeur_ecriture)                      (*s_queue_signaux).pointeur_ecriture)
Line 127  thread_surveillance_signaux(void *argume Line 134  thread_surveillance_signaux(void *argume
                 // appels système lents.                  // appels système lents.
   
                 nombre_signaux_envoyes++;                  nombre_signaux_envoyes++;
                 kill(getpid(), SIGALRM);                  kill(getpid(), SIGUSR2);
                   sched_yield();
             }              }
   
             sem_post(semaphore_queue_signaux);              sem_post(semaphore_queue_signaux);
               sem_post(semaphore_arret_signalisation);
   
             // Dans un second temps, on balaye toutes les queues de signaux              // Dans un second temps, on balaye toutes les queues de signaux
             // des threads du processus courant.              // des threads du processus courant.
Line 154  thread_surveillance_signaux(void *argume Line 163  thread_surveillance_signaux(void *argume
                     if ((*(*((struct_thread *) (*l_element_courant).donnee))                      if ((*(*((struct_thread *) (*l_element_courant).donnee))
                             .s_etat_processus).pointeur_signal_ecriture !=                              .s_etat_processus).pointeur_signal_ecriture !=
                             (*(*((struct_thread *) (*l_element_courant)                              (*(*((struct_thread *) (*l_element_courant)
                             .donnee)).s_etat_processus)                              .donnee)).s_etat_processus).pointeur_signal_lecture)
                             .pointeur_signal_lecture)  
                     {                      {
                         nombre_signaux_envoyes++;                          nombre_signaux_envoyes++;
                         pthread_kill((*((struct_thread *)                          pthread_kill((*((struct_thread *)
                                 (*l_element_courant).donnee)).tid, SIGALRM);                                  (*l_element_courant).donnee)).tid, SIGUSR2);
                           sched_yield();
                     }                      }
   
                     pthread_mutex_unlock(&((*(*((struct_thread *)                      pthread_mutex_unlock(&((*(*((struct_thread *)
Line 207  modification_pid_thread_pere(struct_proc Line 216  modification_pid_thread_pere(struct_proc
 void  void
 insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)  insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)
 {  {
       int                                         ios;
   
       struct timespec                             attente;
   
     volatile struct_liste_chainee_volatile      *l_nouvel_objet;      volatile struct_liste_chainee_volatile      *l_nouvel_objet;
   
     if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))      if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
Line 229  insertion_thread(struct_processus *s_eta Line 242  insertion_thread(struct_processus *s_eta
     (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =      (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
             s_etat_processus;              s_etat_processus;
   
     if (pthread_mutex_lock(&mutex_liste_threads) != 0)      attente.tv_sec = 0;
       attente.tv_nsec = GRANULARITE_us * 1000;
   
       while((ios = pthread_mutex_trylock(&mutex_liste_threads)) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          if (ios != EBUSY)
         return;          {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           nanosleep(&attente, NULL);
           INCR_GRANULARITE(attente.tv_nsec);
   
           while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
           }
     }      }
   
     (*l_nouvel_objet).suivant = liste_threads;      (*l_nouvel_objet).suivant = liste_threads;
Line 260  insertion_thread_surveillance(struct_pro Line 297  insertion_thread_surveillance(struct_pro
         return;          return;
     }      }
   
     if (pthread_mutex_lock(&mutex_liste_threads) != 0)      if (pthread_mutex_lock(&mutex_liste_threads_surveillance) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
Line 275  insertion_thread_surveillance(struct_pro Line 312  insertion_thread_surveillance(struct_pro
   
     liste_threads_surveillance = l_nouvel_objet;      liste_threads_surveillance = l_nouvel_objet;
   
     if (pthread_mutex_unlock(&mutex_liste_threads) != 0)      if (pthread_mutex_unlock(&mutex_liste_threads_surveillance) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
Line 287  insertion_thread_surveillance(struct_pro Line 324  insertion_thread_surveillance(struct_pro
 void  void
 retrait_thread(struct_processus *s_etat_processus)  retrait_thread(struct_processus *s_etat_processus)
 {  {
       int                                     ios;
   
       struct timespec                         attente;
   
     volatile struct_liste_chainee_volatile  *l_element_precedent;      volatile struct_liste_chainee_volatile  *l_element_precedent;
     volatile struct_liste_chainee_volatile  *l_element_courant;      volatile struct_liste_chainee_volatile  *l_element_courant;
   
     if (pthread_mutex_lock(&mutex_liste_threads) != 0)      attente.tv_sec = 0;
       attente.tv_nsec = GRANULARITE_us * 1000;
   
       while((ios = pthread_mutex_trylock(&mutex_liste_threads)) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          if (ios != EBUSY)
         return;          {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           nanosleep(&attente, NULL);
           INCR_GRANULARITE(attente.tv_nsec);
   
           while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
           }
     }      }
   
     l_element_precedent = NULL;      l_element_precedent = NULL;
Line 370  retrait_thread_surveillance(struct_proce Line 435  retrait_thread_surveillance(struct_proce
     volatile struct_liste_chainee_volatile  *l_element_precedent;      volatile struct_liste_chainee_volatile  *l_element_precedent;
     volatile struct_liste_chainee_volatile  *l_element_courant;      volatile struct_liste_chainee_volatile  *l_element_courant;
   
     if (pthread_mutex_lock(&mutex_liste_threads) != 0)      if (pthread_mutex_lock(&mutex_liste_threads_surveillance) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
Line 392  retrait_thread_surveillance(struct_proce Line 457  retrait_thread_surveillance(struct_proce
   
     if (l_element_courant == NULL)      if (l_element_courant == NULL)
     {      {
         pthread_mutex_unlock(&mutex_liste_threads);          pthread_mutex_unlock(&mutex_liste_threads_surveillance);
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
Line 409  retrait_thread_surveillance(struct_proce Line 474  retrait_thread_surveillance(struct_proce
     if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))      if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
             != 0)              != 0)
     {      {
         pthread_mutex_unlock(&mutex_liste_threads);          pthread_mutex_unlock(&mutex_liste_threads_surveillance);
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
Line 425  retrait_thread_surveillance(struct_proce Line 490  retrait_thread_surveillance(struct_proce
         if (pthread_mutex_unlock(&((*s_argument_thread)          if (pthread_mutex_unlock(&((*s_argument_thread)
                 .mutex_nombre_references)) != 0)                  .mutex_nombre_references)) != 0)
         {          {
             pthread_mutex_unlock(&mutex_liste_threads);              pthread_mutex_unlock(&mutex_liste_threads_surveillance);
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
             return;              return;
         }          }
Line 439  retrait_thread_surveillance(struct_proce Line 504  retrait_thread_surveillance(struct_proce
         if (pthread_mutex_unlock(&((*s_argument_thread)          if (pthread_mutex_unlock(&((*s_argument_thread)
                 .mutex_nombre_references)) != 0)                  .mutex_nombre_references)) != 0)
         {          {
             pthread_mutex_unlock(&mutex_liste_threads);              pthread_mutex_unlock(&mutex_liste_threads_surveillance);
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
             return;              return;
         }          }
     }      }
   
     if (pthread_mutex_unlock(&mutex_liste_threads) != 0)      if (pthread_mutex_unlock(&mutex_liste_threads_surveillance) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
Line 458  retrait_thread_surveillance(struct_proce Line 523  retrait_thread_surveillance(struct_proce
 void  void
 verrouillage_threads_concurrents(struct_processus *s_etat_processus)  verrouillage_threads_concurrents(struct_processus *s_etat_processus)
 {  {
       int                                     ios;
   
       struct timespec                         attente;
   
     volatile struct_liste_chainee_volatile  *l_element_courant;      volatile struct_liste_chainee_volatile  *l_element_courant;
   
     if (pthread_mutex_lock(&mutex_liste_threads) != 0)      attente.tv_sec = 0;
       attente.tv_nsec = GRANULARITE_us * 1000;
   
       while((ios = pthread_mutex_trylock(&mutex_liste_threads)) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          if (ios != EBUSY)
         return;          {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           nanosleep(&attente, NULL);
           INCR_GRANULARITE(attente.tv_nsec);
   
           while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
           }
     }      }
   
     l_element_courant = liste_threads;      l_element_courant = liste_threads;
Line 482  verrouillage_threads_concurrents(struct_ Line 575  verrouillage_threads_concurrents(struct_
                         .donnee)).s_etat_processus).semaphore_fork) == -1)                          .donnee)).s_etat_processus).semaphore_fork) == -1)
 #           endif  #           endif
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  if (errno != EINTR)
                 return;                  {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                       return;
                   }
             }              }
         }          }
   
Line 766  liberation_threads(struct_processus *s_e Line 862  liberation_threads(struct_processus *s_e
                 }                  }
             }              }
   
             // ne peut être effacé qu'une seule fois              // Ne peut être effacé qu'une seule fois
             if (suppression_variables_partagees == d_faux)              if (suppression_variables_partagees == d_faux)
             {              {
                 suppression_variables_partagees = d_vrai;                  suppression_variables_partagees = d_vrai;
   
                 liberation_arbre_variables_partagees(s_etat_processus,                  liberation_arbre_variables_partagees(s_etat_processus,
                         (*(*s_etat_processus).s_arbre_variables_partagees));                          (*(*s_etat_processus).s_arbre_variables_partagees));
                   (*(*s_etat_processus).s_arbre_variables_partagees) = NULL;
   
                 l_element_partage_courant = (*(*s_etat_processus)                  l_element_partage_courant = (*(*s_etat_processus)
                         .l_liste_variables_partagees);                          .l_liste_variables_partagees);
Line 784  liberation_threads(struct_processus *s_e Line 881  liberation_threads(struct_processus *s_e
                     free(l_element_partage_courant);                      free(l_element_partage_courant);
                     l_element_partage_courant = l_element_partage_suivant;                      l_element_partage_courant = l_element_partage_suivant;
                 }                  }
   
                   (*(*s_etat_processus).l_liste_variables_partagees) = NULL;
             }              }
   
             liberation_arbre_variables(s_etat_processus,              liberation_arbre_variables(s_etat_processus,
Line 1281  liberation_threads(struct_processus *s_e Line 1380  liberation_threads(struct_processus *s_e
   
     liste_threads = NULL;      liste_threads = NULL;
   
       if (pthread_mutex_unlock(&mutex_liste_threads) == -1)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
       if (pthread_mutex_lock(&mutex_liste_threads_surveillance) == -1)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
     l_element_courant = liste_threads_surveillance;      l_element_courant = liste_threads_surveillance;
   
     while(l_element_courant != NULL)      while(l_element_courant != NULL)
Line 1292  liberation_threads(struct_processus *s_e Line 1403  liberation_threads(struct_processus *s_e
                 != 0)                  != 0)
         {          {
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
             pthread_mutex_unlock(&mutex_liste_threads);              pthread_mutex_unlock(&mutex_liste_threads_surveillance);
             return;              return;
         }          }
   
Line 1315  liberation_threads(struct_processus *s_e Line 1426  liberation_threads(struct_processus *s_e
                     .mutex_nombre_references)) != 0)                      .mutex_nombre_references)) != 0)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                 pthread_mutex_unlock(&mutex_liste_threads);                  pthread_mutex_unlock(&mutex_liste_threads_surveillance);
                 return;                  return;
             }              }
   
Line 1339  liberation_threads(struct_processus *s_e Line 1450  liberation_threads(struct_processus *s_e
                     .mutex_nombre_references)) != 0)                      .mutex_nombre_references)) != 0)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                 pthread_mutex_unlock(&mutex_liste_threads);                  pthread_mutex_unlock(&mutex_liste_threads_surveillance);
                 return;                  return;
             }              }
         }          }
Line 1351  liberation_threads(struct_processus *s_e Line 1462  liberation_threads(struct_processus *s_e
   
     liste_threads_surveillance = NULL;      liste_threads_surveillance = NULL;
   
     if (pthread_mutex_unlock(&mutex_liste_threads) != 0)      if (pthread_mutex_unlock(&mutex_liste_threads_surveillance) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
Line 1459  recherche_thread_principal(pid_t pid) Line 1570  recherche_thread_principal(pid_t pid)
 static inline void  static inline void
 verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)  verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
 {  {
       return;
   
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
     if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)      if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
 #   else  #   else
Line 1475  verrouillage_gestionnaire_signaux(struct Line 1588  verrouillage_gestionnaire_signaux(struct
 static inline void  static inline void
 deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)  deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
 {  {
       return;
   
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
     while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)      while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
 #   else  #   else
Line 1512  lancement_thread_signaux(struct_processu Line 1627  lancement_thread_signaux(struct_processu
 {  {
     pthread_attr_t                  attributs;      pthread_attr_t                  attributs;
   
     void                            *argument;  
   
     if (pipe((*s_etat_processus).pipe_signaux) != 0)      if (pipe((*s_etat_processus).pipe_signaux) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
Line 1534  lancement_thread_signaux(struct_processu Line 1647  lancement_thread_signaux(struct_processu
         return(d_erreur);          return(d_erreur);
     }      }
   
     argument = (*s_etat_processus).pipe_signaux;  
   
     if (pthread_create(&((*s_etat_processus).thread_signaux), &attributs,      if (pthread_create(&((*s_etat_processus).thread_signaux), &attributs,
             thread_signaux, argument) != 0)              thread_signaux, s_etat_processus) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return(d_erreur);
       }
   
       if (pthread_attr_destroy(&attributs) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return(d_erreur);          return(d_erreur);
Line 1556  arret_thread_signaux(struct_processus *s Line 1673  arret_thread_signaux(struct_processus *s
   
     do      do
     {      {
         n = write((*s_etat_processus).pipe_signaux[1], &signal, sizeof(signal));          n = write_atomic(s_etat_processus, (*s_etat_processus).pipe_signaux[1],
                   &signal, sizeof(signal));
   
         if (n < 0)          if (n < 0)
         {          {
Line 1566  arret_thread_signaux(struct_processus *s Line 1684  arret_thread_signaux(struct_processus *s
   
     pthread_join((*s_etat_processus).thread_signaux, NULL);      pthread_join((*s_etat_processus).thread_signaux, NULL);
   
     close((*s_etat_processus).pipe_signaux[0]);  
     close((*s_etat_processus).pipe_signaux[1]);      close((*s_etat_processus).pipe_signaux[1]);
   
     return(d_absence_erreur);      return(d_absence_erreur);
 }  }
   
Line 1581  thread_signaux(void *argument) Line 1697  thread_signaux(void *argument)
   
     struct pollfd           fds;      struct pollfd           fds;
   
       struct_processus        *s_etat_processus;
   
     unsigned char           signal;      unsigned char           signal;
   
     pipe = (int *) argument;      s_etat_processus = (struct_processus *) argument;
       pipe = (*s_etat_processus).pipe_signaux;
     fds.fd = pipe[0];      fds.fd = pipe[0];
     fds.events = POLLIN;      fds.events = POLLIN;
     fds.revents = 0;  
   
     sigfillset(&masque);      sigfillset(&masque);
     pthread_sigmask(SIG_BLOCK, &masque, NULL);      pthread_sigmask(SIG_BLOCK, &masque, NULL);
   
     do      do
     {      {
         if (poll(&fds, 1, -1) == -1)          fds.revents = 0;
   
           while(poll(&fds, 1, -1) == -1)
         {          {
             pthread_exit(NULL);              if (errno != EINTR)
               {
                   close((*s_etat_processus).pipe_signaux[0]);
                   pthread_exit(NULL);
               }
         }          }
   
 #   pragma GCC diagnostic push          if (read_atomic(s_etat_processus, fds.fd, &signal, 1) != 1)
 #   pragma GCC diagnostic ignored "-Wunused-result"          {
               close((*s_etat_processus).pipe_signaux[0]);
         read(fds.fd, &signal, 1);              pthread_exit(NULL);
           }
 #   pragma GCC diagnostic pop  
   
         if (signal != (0xFF & rpl_sigmax))          if (signal != (0xFF & rpl_sigmax))
         {          {
             envoi_signal_processus(getpid(), signal);              envoi_signal_processus(getpid(), signal, d_faux);
             // Un signal SIGALRM est envoyé par le thread de surveillance              // Un signal SIGUSR2 est envoyé par le thread de surveillance
             // des signaux jusqu'à ce que les signaux soient tous traités.              // des signaux jusqu'à ce que les signaux soient tous traités.
         }          }
     } while(signal != (0xFF & rpl_sigmax));      } while(signal != (0xFF & rpl_sigmax));
   
       close((*s_etat_processus).pipe_signaux[0]);
     pthread_exit(NULL);      pthread_exit(NULL);
 }  }
   
   
   static inline void
   _write(int fd, const void *buf, size_t count)
   {
       ssize_t         ios;
   
       while((ios = write(fd, buf, count)) == -1)
       {
           if (errno != EINTR)
           {
               break;
           }
       }
   
       return;
   }
   
   
 // Récupération des signaux  // Récupération des signaux
 // - SIGINT  (arrêt au clavier)  // - SIGINT  (arrêt au clavier)
 // - SIGTERM (signal d'arrêt en provenance du système)  // - SIGTERM (signal d'arrêt en provenance du système)
Line 1627  interruption1(int signal) Line 1769  interruption1(int signal)
   
     test_signal(signal);      test_signal(signal);
   
 #   pragma GCC diagnostic push  
 #   pragma GCC diagnostic ignored "-Wunused-result"  
   
     switch(signal)      switch(signal)
     {      {
         case SIGINT:          case SIGINT:
             signal_tronque = (unsigned char) (rpl_sigint & 0xFF);              signal_tronque = (unsigned char) (rpl_sigint & 0xFF);
             write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));              _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
             break;              break;
   
         case SIGTERM:          case SIGTERM:
             signal_tronque = (unsigned char) (rpl_sigterm & 0xFF);              signal_tronque = (unsigned char) (rpl_sigterm & 0xFF);
             write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));              _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
             break;              break;
   
         case SIGUSR1:          case SIGUSR1:
             signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);              signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);
             write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));              _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
             break;              break;
   
         default:          default:
             // SIGALRM              // SIGUSR2
             break;              break;
     }      }
   
 #   pragma GCC diagnostic pop  
   
     return;      return;
 }  }
   
Line 1675  interruption2(int signal) Line 1812  interruption2(int signal)
     test_signal(signal);      test_signal(signal);
   
     signal_tronque = (unsigned char) (rpl_sigtstp & 0xFF);      signal_tronque = (unsigned char) (rpl_sigtstp & 0xFF);
       _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
 #   pragma GCC diagnostic push  
 #   pragma GCC diagnostic ignored "-Wunused-result"  
   
     write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));  
   
 #   pragma GCC diagnostic pop  
   
     return;      return;
 }  }
Line 1733  interruption4(int signal) Line 1864  interruption4(int signal)
     test_signal(signal);      test_signal(signal);
   
     signal_tronque = (unsigned char) (rpl_sighup & 0xFF);      signal_tronque = (unsigned char) (rpl_sighup & 0xFF);
       _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
 #   pragma GCC diagnostic push  
 #   pragma GCC diagnostic ignored "-Wunused-result"  
   
     write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));  
   
 #   pragma GCC diagnostic pop  
   
     return;      return;
 }  }
Line 1762  interruption5(int signal) Line 1887  interruption5(int signal)
     if (pid_processus_pere == getpid())      if (pid_processus_pere == getpid())
     {      {
         signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);          signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);
         write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));          _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
     }      }
   
     write(STDERR_FILENO, message, strlen(message));      write(STDERR_FILENO, message, strlen(message));
Line 1796  signal_alrm(struct_processus *s_etat_pro Line 1921  signal_alrm(struct_processus *s_etat_pro
         {          {
             // On n'est pas dans le processus père, on remonte le signal.              // On n'est pas dans le processus père, on remonte le signal.
             envoi_signal_processus((*s_etat_processus).pid_processus_pere,              envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                     rpl_sigalrm);                      rpl_sigalrm, d_faux);
         }          }
         else          else
         {          {
Line 1841  signal_term(struct_processus *s_etat_pro Line 1966  signal_term(struct_processus *s_etat_pro
         if ((*s_etat_processus).pid_processus_pere != getpid())          if ((*s_etat_processus).pid_processus_pere != getpid())
         {          {
             envoi_signal_processus((*s_etat_processus).pid_processus_pere,              envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                     rpl_sigterm);                      rpl_sigterm, d_faux);
         }          }
         else          else
         {          {
Line 1879  inline static void Line 2004  inline static void
 signal_int(struct_processus *s_etat_processus, pid_t pid)  signal_int(struct_processus *s_etat_processus, pid_t pid)
 {  {
     struct_processus        *s_thread_principal;      struct_processus        *s_thread_principal;
     volatile sig_atomic_t   exclusion = 0;      pthread_mutex_t         exclusion = PTHREAD_MUTEX_INITIALIZER;
   
     verrouillage_gestionnaire_signaux(s_etat_processus);      verrouillage_gestionnaire_signaux(s_etat_processus);
   
Line 1895  signal_int(struct_processus *s_etat_proc Line 2020  signal_int(struct_processus *s_etat_proc
         if ((*s_etat_processus).pid_processus_pere != getpid())          if ((*s_etat_processus).pid_processus_pere != getpid())
         {          {
             envoi_signal_processus((*s_etat_processus).pid_processus_pere,              envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                     rpl_sigint);                      rpl_sigint, d_faux);
         }          }
         else          else
         {          {
             (*s_etat_processus).var_volatile_traitement_sigint = -1;              (*s_etat_processus).var_volatile_traitement_sigint = -1;
   
             while(exclusion == 1);              pthread_mutex_lock(&exclusion);
             exclusion = 1;  
   
             if ((*s_etat_processus).var_volatile_requete_arret == -1)              if ((*s_etat_processus).var_volatile_requete_arret == -1)
             {              {
                 deverrouillage_gestionnaire_signaux(s_etat_processus);                  deverrouillage_gestionnaire_signaux(s_etat_processus);
                 exclusion = 0;                  pthread_mutex_unlock(&exclusion);
                 return;                  return;
             }              }
   
Line 1925  signal_int(struct_processus *s_etat_proc Line 2049  signal_int(struct_processus *s_etat_proc
             (*s_etat_processus).var_volatile_requete_arret = -1;              (*s_etat_processus).var_volatile_requete_arret = -1;
             (*s_etat_processus).var_volatile_alarme = -1;              (*s_etat_processus).var_volatile_alarme = -1;
   
             exclusion = 0;              pthread_mutex_unlock(&exclusion);
         }          }
     }      }
     else      else
Line 1966  signal_tstp(struct_processus *s_etat_pro Line 2090  signal_tstp(struct_processus *s_etat_pro
         if ((*s_etat_processus).var_volatile_processus_pere == 0)          if ((*s_etat_processus).var_volatile_processus_pere == 0)
         {          {
             envoi_signal_processus((*s_etat_processus).pid_processus_pere,              envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                     rpl_sigtstp);                      rpl_sigtstp, d_faux);
         }          }
         else          else
         {          {
Line 2005  sortie_interruption_depassement_pile(voi Line 2129  sortie_interruption_depassement_pile(voi
     return;      return;
 }  }
   
   #ifdef HAVE_SIGSEGV_RECOVERY
 void  void
 interruption_depassement_pile(int urgence, stackoverflow_context_t scp)  interruption_depassement_pile(int urgence, stackoverflow_context_t scp)
 {  {
Line 2021  interruption_depassement_pile(int urgenc Line 2146  interruption_depassement_pile(int urgenc
     interruption3(SIGUSR2);      interruption3(SIGUSR2);
     return;      return;
 }  }
   #endif
   
 int  int
 interruption_violation_access(void *adresse_fautive, int gravite)  interruption_violation_access(void *adresse_fautive, int gravite)
Line 2034  interruption_violation_access(void *adre Line 2160  interruption_violation_access(void *adre
     {      {
         // Il peut s'agir d'un dépassement de pile.          // Il peut s'agir d'un dépassement de pile.
   
         sigsegv_leave_handler(sortie_interruption_depassement_pile,  #       ifdef HAVE_SIGSEGV_RECOVERY
                 (void *) &routine_recursive, NULL, NULL);              sigsegv_leave_handler(sortie_interruption_depassement_pile,
                       (void *) &routine_recursive, NULL, NULL);
   #       else
               sortie_interruption_depassement_pile((void *) &routine_recursive,
                       NULL, NULL);
   #       endif
     }      }
   
     // On est dans une bonne vieille violation d'accès. On essaie      // On est dans une bonne vieille violation d'accès. On essaie
Line 2347  traitement_exceptions_gsl(const char *re Line 2478  traitement_exceptions_gsl(const char *re
         int line, int gsl_errno)          int line, int gsl_errno)
 {  {
     code_erreur_gsl = gsl_errno;      code_erreur_gsl = gsl_errno;
     envoi_signal_processus(getpid(), rpl_sigexcept);      envoi_signal_processus(getpid(), rpl_sigexcept, d_faux);
     return;      return;
 }  }
   
Line 2459  scrutation_interruptions(struct_processu Line 2590  scrutation_interruptions(struct_processu
             // Il y a un signal en attente dans le segment partagé. On le              // Il y a un signal en attente dans le segment partagé. On le
             // traite.              // traite.
   
               if (pthread_mutex_lock(&mutex_liste_threads) != 0)
               {
                   return;
               }
   
             envoi_interruptions(s_etat_processus,              envoi_interruptions(s_etat_processus,
                     (*s_queue_signaux).queue[(*s_queue_signaux)                      (*s_queue_signaux).queue[(*s_queue_signaux)
                     .pointeur_lecture].signal, (*s_queue_signaux).queue                      .pointeur_lecture].signal, (*s_queue_signaux).queue
Line 2471  scrutation_interruptions(struct_processu Line 2607  scrutation_interruptions(struct_processu
             if (msync(s_queue_signaux, sizeof(s_queue_signaux),              if (msync(s_queue_signaux, sizeof(s_queue_signaux),
                     MS_ASYNC | MS_INVALIDATE) != 0)                      MS_ASYNC | MS_INVALIDATE) != 0)
             {              {
                   sem_post(semaphore_queue_signaux);
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                 return;                  return;
             }              }
 #           endif  #           endif
   
               if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
               {
                   return;
               }
   
             while(sem_wait(semaphore_signalisation) != 0)              while(sem_wait(semaphore_signalisation) != 0)
             {              {
                 if (errno != EINTR)                  if (errno != EINTR)
Line 2491  scrutation_interruptions(struct_processu Line 2633  scrutation_interruptions(struct_processu
   
     // Interruptions qui arrivent depuis le groupe courant de threads.      // Interruptions qui arrivent depuis le groupe courant de threads.
   
     if (pthread_mutex_trylock(&((*s_etat_processus).mutex_signaux)) == 0)      if (pthread_mutex_trylock(&mutex_liste_threads) == 0)
     {      {
         while((*s_etat_processus).pointeur_signal_lecture !=          if (pthread_mutex_trylock(&((*s_etat_processus).mutex_signaux)) == 0)
                 (*s_etat_processus).pointeur_signal_ecriture)  
         {          {
             // Il y a un signal dans la queue du thread courant. On le traite.              while((*s_etat_processus).pointeur_signal_lecture !=
                       (*s_etat_processus).pointeur_signal_ecriture)
               {
                   // Il y a un signal dans la queue du thread courant.
                   // On le traite.
   
             envoi_interruptions(s_etat_processus,                  envoi_interruptions(s_etat_processus,
                     (*s_etat_processus).signaux_en_queue                          (*s_etat_processus).signaux_en_queue
                     [(*s_etat_processus).pointeur_signal_lecture],                          [(*s_etat_processus).pointeur_signal_lecture],
                     getpid());                          getpid());
             (*s_etat_processus).pointeur_signal_lecture =                  (*s_etat_processus).pointeur_signal_lecture =
                     ((*s_etat_processus).pointeur_signal_lecture + 1)                          ((*s_etat_processus).pointeur_signal_lecture + 1)
                     % LONGUEUR_QUEUE_SIGNAUX;                          % LONGUEUR_QUEUE_SIGNAUX;
   
             while(sem_wait(semaphore_signalisation) != 0)                  while(sem_wait(semaphore_signalisation) != 0)
             {  
                 if (errno != EINTR)  
                 {                  {
                     (*s_etat_processus).erreur_systeme = d_es_processus;                      if (errno != EINTR)
                     return;                      {
                           if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
                           {
                               (*s_etat_processus).erreur_systeme = d_es_processus;
                               return;
                           }
   
                           (*s_etat_processus).erreur_systeme = d_es_processus;
                           return;
                       }
                 }                  }
             }              }
   
               pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux));
         }          }
   
         pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux));          pthread_mutex_unlock(&mutex_liste_threads);
     }      }
   
     return;      return;
Line 2588  nom_segment(unsigned char *chemin, pid_t Line 2742  nom_segment(unsigned char *chemin, pid_t
 */  */
   
 int  int
 envoi_signal_processus(pid_t pid, enum signaux_rpl signal)  envoi_signal_processus(pid_t pid, enum signaux_rpl signal,
           logical1 test_ouverture)
 {  {
 #   ifndef OS2  #   ifndef OS2
         int                         segment;          int                         segment;
Line 2608  envoi_signal_processus(pid_t pid, enum s Line 2763  envoi_signal_processus(pid_t pid, enum s
   
     struct_queue_signaux            *queue;      struct_queue_signaux            *queue;
   
       struct timespec                 attente;
   
     unsigned char                   *nom;      unsigned char                   *nom;
   
     // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en      // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en
Line 2643  envoi_signal_processus(pid_t pid, enum s Line 2800  envoi_signal_processus(pid_t pid, enum s
         if (msync(s_queue_signaux, sizeof(s_queue_signaux),          if (msync(s_queue_signaux, sizeof(s_queue_signaux),
                 MS_ASYNC | MS_INVALIDATE) != 0)                  MS_ASYNC | MS_INVALIDATE) != 0)
         {          {
               sem_post(semaphore_queue_signaux);
             return(1);              return(1);
         }          }
 #       endif  #       endif
Line 2668  envoi_signal_processus(pid_t pid, enum s Line 2826  envoi_signal_processus(pid_t pid, enum s
             }              }
   
 #           ifndef OS2 // SysV  #           ifndef OS2 // SysV
                 if ((desc = open(nom, O_RDWR)) == -1)                  if (test_ouverture == d_vrai)
                 {                  {
                     sys_free(nom);                      attente.tv_sec = 0;
                     return(1);                      attente.tv_nsec = GRANULARITE_us * 1000;
   
                       while((desc = open(nom, O_RDWR)) == -1)
                       {
                           nanosleep(&attente, NULL);
                           INCR_GRANULARITE(attente.tv_nsec);
                       }
                   }
                   else
                   {
                       if ((desc = open(nom, O_RDWR)) == -1)
                       {
                           sys_free(nom);
                           return(1);
                       }
                 }                  }
   
                 close(desc);                  close(desc);
Line 2692  envoi_signal_processus(pid_t pid, enum s Line 2864  envoi_signal_processus(pid_t pid, enum s
   
                 queue = shmat(segment, NULL, 0);                  queue = shmat(segment, NULL, 0);
 #           else // OS/2  #           else // OS/2
                 if (DosGetNamedSharedMem((PVOID) &queue, nom,                  if (test_ouverture == d_vrai)
                         PAG_WRITE | PAG_READ) != 0)  
                 {                  {
                     sys_free(nom);                      attente.tv_sec = 0;
                     return(1);                      attente.tv_nsec = GRANULARITE_us * 1000;
   
                       while(DosGetNamedSharedMem((PVOID) &queue, nom,
                               PAG_WRITE | PAG_READ) != 0)
                       {
                           nanosleep(&attente, NULL);
                           INCR_GRANULARITE(attente.tv_nsec);
                       }
                   }
                   else
                   {
                       if (DosGetNamedSharedMem((PVOID) &queue, nom,
                               PAG_WRITE | PAG_READ) != 0)
                       {
                           sys_free(nom);
                           return(1);
                       }
                 }                  }
   
                 sys_free(nom);                  sys_free(nom);
Line 2707  envoi_signal_processus(pid_t pid, enum s Line 2894  envoi_signal_processus(pid_t pid, enum s
                 return(1);                  return(1);
             }              }
   
             if ((segment = shm_open(nom, O_RDWR, 0)) == -1)              if (test_ouverture == d_vrai)
             {              {
                 sys_free(nom);                  attente.tv_sec = 0;
                 return(1);                  attente.tv_nsec = GRANULARITE_us * 1000;
   
                   while((segment = shm_open(nom, O_RDWR, 0)) == -1)
                   {
                       nanosleep(&attente, NULL);
                       INCR_GRANULARITE(attente.tv_nsec);
                   }
               }
               else
               {
                   if ((segment = shm_open(nom, O_RDWR, 0)) == -1)
                   {
                       sys_free(nom);
                       return(1);
                   }
             }              }
   
             sys_free(nom);              sys_free(nom);
Line 2729  envoi_signal_processus(pid_t pid, enum s Line 2930  envoi_signal_processus(pid_t pid, enum s
   
         if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)          if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)
         {          {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                   {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       return(1);
                   }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
             return(1);              return(1);
         }          }
   
         if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))          if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))
                 == SEM_FAILED)                  == SEM_FAILED)
         {          {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                   {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       sem_close(semaphore);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       sem_close(semaphore);
                       return(1);
                   }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           sem_close(semaphore);
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
   
               sem_close(semaphore);
             return(1);              return(1);
         }          }
   
Line 2742  envoi_signal_processus(pid_t pid, enum s Line 2998  envoi_signal_processus(pid_t pid, enum s
         {          {
             if (errno != EINTR)              if (errno != EINTR)
             {              {
   #               ifndef IPCS_SYSV // POSIX
                       if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE)
                               != 0)
                       {
                           munmap(queue, sizeof(struct_queue_signaux));
                           sem_close(semaphore);
                           sem_close(signalisation);
                           close(segment);
                           return(1);
                       }
   
                       if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                       {
                           sem_close(semaphore);
                           sem_close(signalisation);
                           close(segment);
                           return(1);
                       }
   
                       close(segment);
   #               else // IPCS_SYSV
   #                   ifndef OS2 // SysV
                           if (shmdt(queue) != 0)
                           {
                               sem_close(semaphore);
                               sem_close(signalisation);
                               return(1);
                           }
   #                   else // OS/2
                           // Pendant de DosGetNamedSHaredMem()
   #                   endif
   #               endif
   
                 sem_close(semaphore);                  sem_close(semaphore);
                 sem_close(signalisation);                  sem_close(signalisation);
                 return(1);                  return(1);
Line 2754  envoi_signal_processus(pid_t pid, enum s Line 3043  envoi_signal_processus(pid_t pid, enum s
         (*queue).pointeur_ecriture = ((*queue).pointeur_ecriture + 1)          (*queue).pointeur_ecriture = ((*queue).pointeur_ecriture + 1)
                 % LONGUEUR_QUEUE_SIGNAUX;                  % LONGUEUR_QUEUE_SIGNAUX;
   
 #       ifndef IPCS_SYSV  
         if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)  
         {  
             sem_close(semaphore);  
             sem_close(signalisation);  
             return(1);  
         }  
 #       endif  
   
         if (sem_post(semaphore) != 0)          if (sem_post(semaphore) != 0)
         {          {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                   {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       sem_close(semaphore);
                       sem_close(signalisation);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       sem_close(semaphore);
                       sem_close(signalisation);
                       return(1);
                   }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           sem_close(semaphore);
                           sem_close(signalisation);
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
   
             sem_close(semaphore);              sem_close(semaphore);
             sem_close(signalisation);              sem_close(signalisation);
             return(1);              return(1);
Line 2772  envoi_signal_processus(pid_t pid, enum s Line 3084  envoi_signal_processus(pid_t pid, enum s
   
         if (sem_close(semaphore) != 0)          if (sem_close(semaphore) != 0)
         {          {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                   {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       sem_close(signalisation);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       sem_close(signalisation);
                       return(1);
                   }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           sem_close(signalisation);
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
   
               sem_close(signalisation);
             return(1);              return(1);
         }          }
   
         if (sem_post(signalisation) != 0)          if (sem_post(signalisation) != 0)
         {          {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                   {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       sem_close(signalisation);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       sem_close(signalisation);
                       return(1);
                   }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           sem_close(signalisation);
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
   
             sem_close(signalisation);              sem_close(signalisation);
             return(1);              return(1);
         }          }
   
         if (sem_close(signalisation) != 0)          if (sem_close(signalisation) != 0)
         {          {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                   {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       return(1);
                   }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
   
             return(1);              return(1);
         }          }
   
 #       ifndef IPCS_SYSV // POSIX  #       ifndef IPCS_SYSV // POSIX
               if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
               {
                   munmap(queue, sizeof(struct_queue_signaux));
                   close(segment);
                   return(1);
               }
   
             if (munmap(queue, sizeof(struct_queue_signaux)) != 0)              if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
             {              {
                 close(segment);                  close(segment);
                 return(1);                  return(1);
             }              }
   
               close(segment);
 #       else // IPCS_SYSV  #       else // IPCS_SYSV
 #           ifndef OS2 // SysV  #           ifndef OS2 // SysV
                 if (shmdt(queue) != 0)                  if (shmdt(queue) != 0)
Line 2808  envoi_signal_processus(pid_t pid, enum s Line 3214  envoi_signal_processus(pid_t pid, enum s
 }  }
   
 int  int
 envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)  envoi_signal_thread(struct_processus *s_contexte,
           pthread_t tid, enum signaux_rpl signal)
 {  {
     // Un signal est envoyé d'un thread à un autre thread du même processus.      // Un signal est envoyé d'un thread à un autre thread du même processus.
   
       int                                     ios;
   
       struct timespec                         attente;
   
     volatile struct_liste_chainee_volatile  *l_element_courant;      volatile struct_liste_chainee_volatile  *l_element_courant;
   
     struct_processus                        *s_etat_processus;      struct_processus                        *s_etat_processus;
   
     if (pthread_mutex_lock(&mutex_liste_threads) != 0)      if (s_contexte != NULL)
     {      {
         return(1);          attente.tv_sec = 0;
           attente.tv_nsec = GRANULARITE_us * 1000;
   
           while((ios = pthread_mutex_trylock(&mutex_liste_threads)) != 0)
           {
               if (ios != EBUSY)
               {
                   return(1);
               }
   
               if (sem_post(&((*s_contexte).semaphore_fork)) != 0)
               {
                   return(1);
               }
   
               nanosleep(&attente, NULL);
               INCR_GRANULARITE(attente.tv_nsec);
   
               while(sem_wait(&((*s_contexte).semaphore_fork)) != 0)
               {
                   if (errno != EINTR)
                   {
                       return(1);
                   }
               }
           }
       }
       else
       {
           if (pthread_mutex_lock(&mutex_liste_threads) != 0)
           {
               return(1);
           }
     }      }
   
     l_element_courant = liste_threads;      l_element_courant = liste_threads;
Line 2886  envoi_signal_contexte(struct_processus * Line 3329  envoi_signal_contexte(struct_processus *
     (*s_etat_processus_a_signaler).pointeur_signal_ecriture =      (*s_etat_processus_a_signaler).pointeur_signal_ecriture =
             ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)              ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)
             % LONGUEUR_QUEUE_SIGNAUX;              % LONGUEUR_QUEUE_SIGNAUX;
       pthread_kill((*s_etat_processus_a_signaler).tid, SIGUSR2);
     pthread_mutex_unlock(&((*s_etat_processus_a_signaler).mutex_signaux));      pthread_mutex_unlock(&((*s_etat_processus_a_signaler).mutex_signaux));
   
     if (sem_post(semaphore_signalisation) != 0)      if (sem_post(semaphore_signalisation) != 0)
Line 2930  creation_queue_signaux(struct_processus Line 3374  creation_queue_signaux(struct_processus
         if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,          if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
                 S_IRUSR | S_IWUSR)) == -1)                  S_IRUSR | S_IWUSR)) == -1)
         {          {
             sys_free(nom);              if (errno != EEXIST)
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              {
             return;                  sys_free(nom);
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               if ((*s_etat_processus).langue == 'F')
               {
                   printf("+++Attention : Le segment de mémoire %s préexiste !\n",
                           nom);
               }
               else
               {
                   printf("+++Warning: %s memory segment preexists!\n", nom);
               }
   
               if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_TRUNC,
                       S_IRUSR | S_IWUSR)) == -1)
               {
                   sys_free(nom);
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
         }          }
   
         if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)          if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)
Line 2987  creation_queue_signaux(struct_processus Line 3452  creation_queue_signaux(struct_processus
   
         (*s_queue_signaux).requete_arret = d_faux;          (*s_queue_signaux).requete_arret = d_faux;
   
         if (msync(s_queue_signaux, sizeof(struct_queue_signaux), MS_SYNC))          if (msync(s_queue_signaux, sizeof(struct_queue_signaux),
                   MS_ASYNC | MS_INVALIDATE) != 0)
         {          {
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
             return;              return;
Line 3090  creation_queue_signaux(struct_processus Line 3556  creation_queue_signaux(struct_processus
   
             sys_free(nom);              sys_free(nom);
   
             sem_init(&((*s_queue_signaux).semaphore), 1, 1);              if (sem_init(&((*s_queue_signaux).semaphore), 1, 1) != 0)
             sem_init(&((*s_queue_signaux).signalisation), 1, 0);              {
             sem_init(&((*s_queue_signaux).arret_signalisation), 1, 1);                  (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               if (sem_init(&((*s_queue_signaux).signalisation), 1, 0) != 0)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               if (sem_init(&((*s_queue_signaux).arret_signalisation), 1, 1) != 0)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
             (*s_queue_signaux).pointeur_lecture = 0;              (*s_queue_signaux).pointeur_lecture = 0;
             (*s_queue_signaux).pointeur_ecriture = 0;              (*s_queue_signaux).pointeur_ecriture = 0;
Line 3100  creation_queue_signaux(struct_processus Line 3580  creation_queue_signaux(struct_processus
 #       endif  #       endif
 #   endif  #   endif
   
     // Lancement du thread de récupération des signaux.      (*s_queue_signaux).controle = getpid();
   
     if (pthread_attr_init(&attributs) != 0)      if (lancement_thread_signaux(s_etat_processus) == d_erreur)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
   
     if (pthread_attr_setdetachstate(&attributs,      // Lancement du thread de récupération des signaux.
             PTHREAD_CREATE_JOINABLE) != 0)  
     {  
         (*s_etat_processus).erreur_systeme = d_es_processus;  
         return;  
     }  
   
 #   ifdef SCHED_OTHER      if (pthread_attr_init(&attributs) != 0)
     if (pthread_attr_setschedpolicy(&attributs, SCHED_OTHER) != 0)  
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
 #   endif  
   
 #   ifdef PTHREAD_EXPLICIT_SCHED      if (pthread_attr_setdetachstate(&attributs,
     if (pthread_attr_setinheritsched(&attributs, PTHREAD_EXPLICIT_SCHED) != 0)              PTHREAD_CREATE_JOINABLE) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
 #   endif  
   
 #   ifdef PTHREAD_SCOPE_SYSTEM      if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs,
     if (pthread_attr_setscope(&attributs, PTHREAD_SCOPE_SYSTEM) != 0)              thread_surveillance_signaux, s_etat_processus) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
 #   endif  
   
     if (pthread_attr_destroy(&attributs) != 0)      if (pthread_attr_destroy(&attributs) != 0)
     {      {
Line 3145  creation_queue_signaux(struct_processus Line 3616  creation_queue_signaux(struct_processus
         return;          return;
     }      }
   
     if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs,  #   ifndef IPCS_SYSV
             thread_surveillance_signaux, s_etat_processus) != 0)      if (msync(s_queue_signaux, sizeof(s_queue_signaux),
               MS_ASYNC | MS_INVALIDATE) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
   #   endif
   
     return;      return;
 }  }
Line 3172  creation_queue_signaux(struct_processus Line 3645  creation_queue_signaux(struct_processus
 void  void
 liberation_queue_signaux(struct_processus *s_etat_processus)  liberation_queue_signaux(struct_processus *s_etat_processus)
 {  {
     sem_wait(semaphore_arret_signalisation);  
     (*s_queue_signaux).requete_arret = d_vrai;  
   
 #   ifndef IPCS_SYSV  
     msync(s_queue_signaux, sizeof(s_queue_signaux), MS_ASYNC | MS_INVALIDATE);  
 #   endif  
   
     sem_post(semaphore_arret_signalisation);  
   
     // Incrémenter le sémaphore pour être sûr de le débloquer.  
   
     sem_post(semaphore_signalisation);  
     pthread_join((*s_queue_signaux).thread_signaux, NULL);  
   
 #   ifdef IPCS_SYSV // SystemV  #   ifdef IPCS_SYSV // SystemV
 #       ifndef OS2  #       ifndef OS2
             if (shmdt(s_queue_signaux) == -1)              if (shmdt(s_queue_signaux) == -1)
Line 3233  destruction_queue_signaux(struct_process Line 3692  destruction_queue_signaux(struct_process
         unsigned char       *nom;          unsigned char       *nom;
 #   endif  #   endif
   
     sem_wait(semaphore_arret_signalisation);      // On dépile les interruptions pour arrêter les SIGUSR2 sur
       // le processus courant.
   
       scrutation_interruptions(s_etat_processus);
   
       while(sem_wait(semaphore_arret_signalisation) != 0)
       {
           if (errno != EINTR)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
       }
   
     (*s_queue_signaux).requete_arret = d_vrai;      (*s_queue_signaux).requete_arret = d_vrai;
   
Line 3246  destruction_queue_signaux(struct_process Line 3717  destruction_queue_signaux(struct_process
     // Incrémenter le sémaphore pour être sûr de le débloquer.      // Incrémenter le sémaphore pour être sûr de le débloquer.
   
     sem_post(semaphore_signalisation);      sem_post(semaphore_signalisation);
     pthread_join((*s_queue_signaux).thread_signaux, NULL);  
       if ((*s_queue_signaux).controle == getpid())
       {
           pthread_join((*s_queue_signaux).thread_signaux, NULL);
       }
       else
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
       arret_thread_signaux(s_etat_processus);
   
 #   ifdef IPCS_SYSV // SystemV  #   ifdef IPCS_SYSV // SystemV
 #       ifndef OS2  #       ifndef OS2

Removed from v.1.154  
changed lines
  Added in v.1.208


CVSweb interface <joel.bertrand@systella.fr>