Diff for /rpl/src/interruptions.c between versions 1.101 and 1.152

version 1.101, 2012/08/22 10:47:18 version 1.152, 2015/01/08 14:30:58
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.10    RPL/2 (R) version 4.1.20
   Copyright (C) 1989-2012 Dr. BERTRAND Joël    Copyright (C) 1989-2015 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
   
Line 60  static volatile int        code_erreur_g Line 60  static volatile int        code_erreur_g
   
 unsigned char                                   *racine_segment;  unsigned char                                   *racine_segment;
   
 static pthread_mutex_t                          mutex_interruptions  
         = PTHREAD_MUTEX_INITIALIZER;  
   
 static void *  static void *
 thread_surveillance_signaux(void *argument)  thread_surveillance_signaux(void *argument)
 {  {
Line 81  thread_surveillance_signaux(void *argume Line 78  thread_surveillance_signaux(void *argume
   
     volatile struct_liste_chainee_volatile  *l_element_courant;      volatile struct_liste_chainee_volatile  *l_element_courant;
   
       sigset_t                                set;
   
       sigfillset(&set);
       pthread_sigmask(SIG_BLOCK, &set, NULL);
   
     s_etat_processus = (struct_processus *) argument;      s_etat_processus = (struct_processus *) argument;
   
     for(;;)      for(;;)
Line 88  thread_surveillance_signaux(void *argume Line 90  thread_surveillance_signaux(void *argume
         attente.tv_sec = 0;          attente.tv_sec = 0;
         attente.tv_nsec = GRANULARITE_us * 1000;          attente.tv_nsec = GRANULARITE_us * 1000;
   
 #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)          if (sem_wait(semaphore_signalisation) == 0)
         if (sem_wait(&(*s_queue_signaux).signalisation) == 0)  
 #       else  
         if(sem_wait(semaphore_signalisation) == 0)  
 #       endif  
         {          {
               if (sem_wait(semaphore_arret_signalisation) != 0)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
               }
   
             if ((*s_queue_signaux).requete_arret == d_vrai)              if ((*s_queue_signaux).requete_arret == d_vrai)
             {              {
                   sem_post(semaphore_arret_signalisation);
                   sem_post(semaphore_signalisation);
   
                 break;                  break;
             }              }
   
 #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)              sem_post(semaphore_arret_signalisation);
             sem_post(&(*s_queue_signaux).signalisation);  
 #           else  
             sem_post(semaphore_signalisation);              sem_post(semaphore_signalisation);
 #           endif  
   
             nombre_signaux_envoyes = 0;              nombre_signaux_envoyes = 0;
             sched_yield();              sched_yield();
Line 112  thread_surveillance_signaux(void *argume Line 115  thread_surveillance_signaux(void *argume
             // 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.
   
 #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)  
             sem_wait(&(*s_queue_signaux).semaphore);  
 #           else  
             sem_wait(semaphore_queue_signaux);              sem_wait(semaphore_queue_signaux);
 #           endif  
   
             if ((*s_queue_signaux).pointeur_lecture !=              if ((*s_queue_signaux).pointeur_lecture !=
                     (*s_queue_signaux).pointeur_ecriture)                      (*s_queue_signaux).pointeur_ecriture)
             {              {
                   // Attention : raise() envoit le signal au thread appelant !
                   // kill() l'envoie au processus appelant, donc dans notre
                   // cas à un thread aléatoire du processus, ce qui nous
                   // convient tout à fait puisqu'il s'agit de débloquer les
                   // appels système lents.
   
                 nombre_signaux_envoyes++;                  nombre_signaux_envoyes++;
                 raise(SIGALRM);                  kill(getpid(), SIGALRM);
             }              }
   
 #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)  
             sem_post(&(*s_queue_signaux).semaphore);  
 #           else  
             sem_post(semaphore_queue_signaux);              sem_post(semaphore_queue_signaux);
 #           endif  
   
             // 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.
   
               // Attention : l'ordre de verrouillage des mutexes est important
               // pour éviter les conditions bloquantes !
   
             pthread_mutex_lock(&mutex_liste_threads);              pthread_mutex_lock(&mutex_liste_threads);
   
             l_element_courant = liste_threads;              l_element_courant = liste_threads;
   
             while(l_element_courant != NULL)              while(l_element_courant != NULL)
Line 142  thread_surveillance_signaux(void *argume Line 147  thread_surveillance_signaux(void *argume
                 if ((*((struct_thread *) (*l_element_courant).donnee)).pid                  if ((*((struct_thread *) (*l_element_courant).donnee)).pid
                         == getpid())                          == getpid())
                 {                  {
                       pthread_mutex_lock(&((*(*((struct_thread *)
                               (*l_element_courant).donnee)).s_etat_processus)
                               .mutex_signaux));
   
                     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).donnee))                              (*(*((struct_thread *) (*l_element_courant)
                             .s_etat_processus).pointeur_signal_lecture)                              .donnee)).s_etat_processus)
                               .pointeur_signal_lecture)
                     {                      {
                         nombre_signaux_envoyes++;                          nombre_signaux_envoyes++;
                         pthread_kill((*((struct_thread *) (*l_element_courant)                          pthread_kill((*((struct_thread *)
                                 .donnee)).tid, SIGALRM);                                  (*l_element_courant).donnee)).tid, SIGALRM);
                     }                      }
   
                       pthread_mutex_unlock(&((*(*((struct_thread *)
                               (*l_element_courant).donnee)).s_etat_processus)
                               .mutex_signaux));
                 }                  }
   
                 l_element_courant = (*l_element_courant).suivant;                  l_element_courant = (*l_element_courant).suivant;
Line 167  thread_surveillance_signaux(void *argume Line 181  thread_surveillance_signaux(void *argume
         }          }
         else          else
         {          {
             (*s_etat_processus).erreur_systeme = d_es_processus;              if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
               }
         }          }
     }      }
   
Line 325  retrait_thread(struct_processus *s_etat_ Line 342  retrait_thread(struct_processus *s_etat_
             (*l_element_courant).donnee)).s_etat_processus)              (*l_element_courant).donnee)).s_etat_processus)
             .pointeur_signal_lecture)              .pointeur_signal_lecture)
     {      {
 #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)          while(sem_wait(semaphore_signalisation) != 0)
         sem_wait(&((*s_queue_signaux).signalisation));          {
 #       else              if (errno != EINTR)
         sem_wait(semaphore_signalisation);              {
 #       endif                  (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
           }
   
         (*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus)          (*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus)
                 .pointeur_signal_lecture = ((*(*((struct_thread *)                  .pointeur_signal_lecture = ((*(*((struct_thread *)
Line 528  liberation_threads(struct_processus *s_e Line 548  liberation_threads(struct_processus *s_e
   
     struct_processus                            *candidat;      struct_processus                            *candidat;
   
     unsigned long                               i;      struct_liste_variables_partagees            *l_element_partage_courant;
       struct_liste_variables_partagees            *l_element_partage_suivant;
   
       struct_liste_variables_statiques            *l_element_statique_courant;
       struct_liste_variables_statiques            *l_element_statique_suivant;
   
       integer8                                    i;
   
     void                                        *element_candidat;      void                                        *element_candidat;
     void                                        *element_courant;      void                                        *element_courant;
Line 571  liberation_threads(struct_processus *s_e Line 597  liberation_threads(struct_processus *s_e
             close((*s_etat_processus).pipe_injections);              close((*s_etat_processus).pipe_injections);
             close((*s_etat_processus).pipe_nombre_injections);              close((*s_etat_processus).pipe_nombre_injections);
             close((*s_etat_processus).pipe_interruptions);              close((*s_etat_processus).pipe_interruptions);
             close((*s_etat_processus).pipe_nombre_objets_attente);              close((*s_etat_processus).pipe_nombre_elements_attente);
             close((*s_etat_processus).pipe_nombre_interruptions_attente);  
   
             liberation(s_etat_processus, (*s_etat_processus).at_exit);              liberation(s_etat_processus, (*s_etat_processus).at_exit);
   
Line 640  liberation_threads(struct_processus *s_e Line 665  liberation_threads(struct_processus *s_e
                     close((*s_argument_thread).pipe_acquittement[1]);                      close((*s_argument_thread).pipe_acquittement[1]);
                     close((*s_argument_thread).pipe_injections[1]);                      close((*s_argument_thread).pipe_injections[1]);
                     close((*s_argument_thread).pipe_nombre_injections[1]);                      close((*s_argument_thread).pipe_nombre_injections[1]);
                     close((*s_argument_thread).pipe_nombre_objets_attente[0]);                      close((*s_argument_thread).pipe_nombre_elements_attente[0]);
                     close((*s_argument_thread).pipe_interruptions[0]);                      close((*s_argument_thread).pipe_interruptions[0]);
                     close((*s_argument_thread)  
                             .pipe_nombre_interruptions_attente[0]);  
   
                     if (pthread_mutex_unlock(&((*s_argument_thread)                      if (pthread_mutex_unlock(&((*s_argument_thread)
                             .mutex_nombre_references)) != 0)                              .mutex_nombre_references)) != 0)
Line 743  liberation_threads(struct_processus *s_e Line 766  liberation_threads(struct_processus *s_e
                 }                  }
             }              }
   
             liberation_arbre_variables(s_etat_processus,              // ne peut être effacé qu'une seule fois
                     (*s_etat_processus).s_arbre_variables, d_faux);  
   
             for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)  
             {  
                 pthread_mutex_trylock(&((*(*s_etat_processus)  
                         .s_liste_variables_statiques[i].objet).mutex));  
                 pthread_mutex_unlock(&((*(*s_etat_processus)  
                         .s_liste_variables_statiques[i].objet).mutex));  
   
                 liberation(s_etat_processus, (*s_etat_processus)  
                         .s_liste_variables_statiques[i].objet);  
                 free((*s_etat_processus).s_liste_variables_statiques[i].nom);  
             }  
   
             free((*s_etat_processus).s_liste_variables_statiques);  
   
             // 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;
   
                 for(i = 0; i < (*(*s_etat_processus)                  liberation_arbre_variables_partagees(s_etat_processus,
                         .s_liste_variables_partagees).nombre_variables; i++)                          (*(*s_etat_processus).s_arbre_variables_partagees));
                 {  
                     pthread_mutex_trylock(&((*(*(*s_etat_processus)  
                             .s_liste_variables_partagees).table[i].objet)  
                             .mutex));  
                     pthread_mutex_unlock(&((*(*(*s_etat_processus)  
                             .s_liste_variables_partagees).table[i].objet)  
                             .mutex));  
   
                     liberation(s_etat_processus, (*(*s_etat_processus)                  l_element_partage_courant = (*(*s_etat_processus)
                             .s_liste_variables_partagees).table[i].objet);                          .l_liste_variables_partagees);
                     free((*(*s_etat_processus).s_liste_variables_partagees)  
                             .table[i].nom);  
                 }  
   
                 if ((*(*s_etat_processus).s_liste_variables_partagees).table                  while(l_element_partage_courant != NULL)
                         != NULL)  
                 {                  {
                     free((struct_variable_partagee *) (*(*s_etat_processus)                      l_element_partage_suivant =
                             .s_liste_variables_partagees).table);                              (*l_element_partage_courant).suivant;
                       free(l_element_partage_courant);
                       l_element_partage_courant = l_element_partage_suivant;
                 }                  }
               }
   
                 pthread_mutex_trylock(&((*(*s_etat_processus)              liberation_arbre_variables(s_etat_processus,
                         .s_liste_variables_partagees).mutex));                      (*s_etat_processus).s_arbre_variables, d_faux);
                 pthread_mutex_unlock(&((*(*s_etat_processus)  
                         .s_liste_variables_partagees).mutex));              l_element_statique_courant = (*s_etat_processus)
                       .l_liste_variables_statiques;
   
               while(l_element_statique_courant != NULL)
               {
                   l_element_statique_suivant =
                       (*l_element_statique_courant).suivant;
                   free(l_element_statique_courant);
                   l_element_statique_courant = l_element_statique_suivant;
             }              }
   
             element_courant = (*s_etat_processus).l_base_pile;              element_courant = (*s_etat_processus).l_base_pile;
Line 1301  liberation_threads(struct_processus *s_e Line 1307  liberation_threads(struct_processus *s_e
             close((*s_argument_thread).pipe_acquittement[1]);              close((*s_argument_thread).pipe_acquittement[1]);
             close((*s_argument_thread).pipe_injections[1]);              close((*s_argument_thread).pipe_injections[1]);
             close((*s_argument_thread).pipe_nombre_injections[1]);              close((*s_argument_thread).pipe_nombre_injections[1]);
             close((*s_argument_thread).pipe_nombre_objets_attente[0]);              close((*s_argument_thread).pipe_nombre_elements_attente[0]);
             close((*s_argument_thread).pipe_interruptions[0]);              close((*s_argument_thread).pipe_interruptions[0]);
             close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);  
   
             if (pthread_mutex_unlock(&((*s_argument_thread)              if (pthread_mutex_unlock(&((*s_argument_thread)
                     .mutex_nombre_references)) != 0)                      .mutex_nombre_references)) != 0)
Line 1361  recherche_thread(pid_t pid, pthread_t ti Line 1366  recherche_thread(pid_t pid, pthread_t ti
   
     struct_processus                            *s_etat_processus;      struct_processus                            *s_etat_processus;
   
       if (pthread_mutex_lock(&mutex_liste_threads) != 0)
       {
           return(NULL);
       }
   
     l_element_courant = liste_threads;      l_element_courant = liste_threads;
   
     while(l_element_courant != NULL)      while(l_element_courant != NULL)
Line 1381  recherche_thread(pid_t pid, pthread_t ti Line 1391  recherche_thread(pid_t pid, pthread_t ti
          * Le processus n'existe plus. On ne distribue aucun signal.           * Le processus n'existe plus. On ne distribue aucun signal.
          */           */
   
           pthread_mutex_unlock(&mutex_liste_threads);
         return(NULL);          return(NULL);
     }      }
   
     s_etat_processus = (*((struct_thread *)      s_etat_processus = (*((struct_thread *)
             (*l_element_courant).donnee)).s_etat_processus;              (*l_element_courant).donnee)).s_etat_processus;
   
       if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
       {
           return(NULL);
       }
   
     return(s_etat_processus);      return(s_etat_processus);
 }  }
   
Line 1442  recherche_thread_principal(pid_t pid) Line 1458  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)
 {  {
     int         semaphore;  
   
 #   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 1454  verrouillage_gestionnaire_signaux(struct Line 1468  verrouillage_gestionnaire_signaux(struct
         return;          return;
     }      }
   
     // Il faut respecteur l'atomicité des deux opérations suivantes !      return;
   }
     if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) != 0)  
     {  
 #       ifndef SEMAPHORES_NOMMES  
         sem_wait(&((*s_etat_processus).semaphore_fork));  
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }  
   
 #   ifndef SEMAPHORES_NOMMES  
     if (sem_post(&semaphore_gestionnaires_signaux) == -1)  
 #   else  
     if (sem_post(semaphore_gestionnaires_signaux) == -1)  
 #   endif  
     {  
 #       ifndef SEMAPHORES_NOMMES  
         sem_wait(&((*s_etat_processus).semaphore_fork));  
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Lock error !\n"));  
         return;  
     }  
   
   static inline void
   deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
   {
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)      while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
 #   else  #   else
     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)      while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
 #   endif  #   endif
     {      {
 #       ifndef SEMAPHORES_NOMMES          if (errno != EINTR)
         sem_wait(&((*s_etat_processus).semaphore_fork));  
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Lock error !\n"));  
         return;  
     }  
   
     if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)  
     {  
 #       ifndef SEMAPHORES_NOMMES  
         sem_wait(&((*s_etat_processus).semaphore_fork));  
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }  
   
     if (semaphore == 1)  
     {  
         // Le semaphore ne peut être pris par le thread qui a appelé  
         // le gestionnaire de signal car le signal est bloqué par ce thread  
         // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que  
         // par un thread concurrent. On essaye donc de le bloquer jusqu'à  
         // ce que ce soit possible.  
   
         if (pthread_mutex_lock(&mutex_liste_threads) != 0)  
         {          {
 #           ifndef SEMAPHORES_NOMMES              BUG(1, uprintf("Unlock error !\n"));
             sem_wait(&((*s_etat_processus).semaphore_fork));  
 #           else  
             sem_wait((*s_etat_processus).semaphore_fork);  
 #           endif  
             BUG(1, uprintf("Lock error !\n"));  
             return;              return;
         }          }
     }      }
Line 1531  verrouillage_gestionnaire_signaux(struct Line 1490  verrouillage_gestionnaire_signaux(struct
     return;      return;
 }  }
   
 static inline void  /*
 deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)  ================================================================================
     Fonctions de gestion des signaux dans les threads.
   
     Lorsqu'un processus reçoit un signal, il appelle le gestionnaire de signal
     associé qui ne fait qu'envoyer au travers de write() le signal
     reçus dans un pipe. Un second thread est bloqué sur ce pipe et
     effectue le traitement adéquat pour le signal donné.
   ================================================================================
   */
   
   #define test_signal(signal) \
       if (signal_test == SIGTEST) { signal_test = signal; return; }
   
   static int          pipe_signaux;
   
   logical1
   lancement_thread_signaux(struct_processus *s_etat_processus)
 {  {
     int         semaphore;      pthread_attr_t                  attributs;
   
     // Il faut respecteur l'atomicité des deux opérations suivantes !      void                            *argument;
   
     if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) == -1)      if (pipe((*s_etat_processus).pipe_signaux) != 0)
     {      {
 #       ifndef SEMAPHORES_NOMMES          (*s_etat_processus).erreur_systeme = d_es_processus;
         sem_wait(&((*s_etat_processus).semaphore_fork));          return(d_erreur);
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      pipe_signaux = (*s_etat_processus).pipe_signaux[1];
     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)  
 #   else      if (pthread_attr_init(&attributs) != 0)
     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)  
 #   endif  
     {      {
 #       ifndef SEMAPHORES_NOMMES          (*s_etat_processus).erreur_systeme = d_es_processus;
         sem_wait(&((*s_etat_processus).semaphore_fork));          return(d_erreur);
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_attr_setdetachstate(&attributs, PTHREAD_CREATE_JOINABLE) != 0)
     while(sem_wait(&semaphore_gestionnaires_signaux) == -1)  
 #   else  
     while(sem_wait(semaphore_gestionnaires_signaux) == -1)  
 #   endif  
     {      {
         if (errno != EINTR)          (*s_etat_processus).erreur_systeme = d_es_processus;
         {          return(d_erreur);
 #           ifndef SEMAPHORES_NOMMES  
             sem_wait(&((*s_etat_processus).semaphore_fork));  
 #           else  
             sem_wait((*s_etat_processus).semaphore_fork);  
 #           endif  
             BUG(1, uprintf("Unlock error !\n"));  
             return;  
         }  
     }      }
   
     if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)      argument = (*s_etat_processus).pipe_signaux;
   
       if (pthread_create(&((*s_etat_processus).thread_signaux), &attributs,
               thread_signaux, argument) != 0)
     {      {
 #       ifndef SEMAPHORES_NOMMES          (*s_etat_processus).erreur_systeme = d_es_processus;
         sem_wait(&((*s_etat_processus).semaphore_fork));          return(d_erreur);
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      return(d_absence_erreur);
     while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)  }
 #   else  
     while(sem_wait((*s_etat_processus).semaphore_fork) != 0)  logical1
 #   endif  arret_thread_signaux(struct_processus *s_etat_processus)
   {
       unsigned char       signal;
       ssize_t             n;
   
       signal = (unsigned char ) (rpl_sigmax & 0xFF);
   
       do
     {      {
         if (errno != EINTR)          n = write((*s_etat_processus).pipe_signaux[1], &signal, sizeof(signal));
   
           if (n < 0)
         {          {
             BUG(1, uprintf("Unlock error !\n"));              return(d_erreur);
             return;  
         }          }
     }      } while(n != 1);
   
       pthread_join((*s_etat_processus).thread_signaux, NULL);
   
       close((*s_etat_processus).pipe_signaux[0]);
       close((*s_etat_processus).pipe_signaux[1]);
   
       return(d_absence_erreur);
   }
   
     if (semaphore == 1)  void *
   thread_signaux(void *argument)
   {
       int                     *pipe;
   
       sigset_t                masque;
   
       struct pollfd           fds;
   
       unsigned char           signal;
   
       pipe = (int *) argument;
       fds.fd = pipe[0];
       fds.events = POLLIN;
       fds.revents = 0;
   
       sigfillset(&masque);
       pthread_sigmask(SIG_BLOCK, &masque, NULL);
   
       do
     {      {
         if (pthread_mutex_unlock(&mutex_liste_threads) != 0)          if (poll(&fds, 1, -1) == -1)
         {          {
             BUG(1, uprintf("Unlock error !\n"));              pthread_exit(NULL);
             return;  
         }          }
     }  
   
     return;  #   pragma GCC diagnostic push
 }  #   pragma GCC diagnostic ignored "-Wunused-result"
   
 #define test_signal(signal) \          read(fds.fd, &signal, 1);
     if (signal_test == SIGTEST) { signal_test = signal; return; }  
   #   pragma GCC diagnostic pop
   
           if (signal != (0xFF & rpl_sigmax))
           {
               envoi_signal_processus(getpid(), signal);
               // Un signal SIGALRM est envoyé par le thread de surveillance
               // des signaux jusqu'à ce que les signaux soient tous traités.
           }
       } while(signal != (0xFF & rpl_sigmax));
   
       pthread_exit(NULL);
   }
   
 // Récupération des signaux  // Récupération des signaux
 // - SIGINT  (arrêt au clavier)  // - SIGINT  (arrêt au clavier)
Line 1628  deverrouillage_gestionnaire_signaux(stru Line 1622  deverrouillage_gestionnaire_signaux(stru
 void  void
 interruption1(int signal)  interruption1(int signal)
 {  {
       unsigned char       signal_tronque;
   
     test_signal(signal);      test_signal(signal);
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
     switch(signal)      switch(signal)
     {      {
         case SIGINT:          case SIGINT:
             envoi_signal_processus(getpid(), rpl_sigint);              signal_tronque = (unsigned char) (rpl_sigint & 0xFF);
               write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
             break;              break;
   
         case SIGTERM:          case SIGTERM:
             envoi_signal_processus(getpid(), rpl_sigterm);              signal_tronque = (unsigned char) (rpl_sigterm & 0xFF);
               write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
             break;              break;
   
         case SIGUSR1:          case SIGUSR1:
             envoi_signal_processus(getpid(), rpl_sigalrm);              signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);
               write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
               break;
   
           default:
               // SIGALRM
             break;              break;
     }      }
   
   #   pragma GCC diagnostic pop
   
       return;
   }
   
   // Récupération des signaux
   // - SIGFSTP
   //
   // ATTENTION :
   // Le signal SIGFSTP provient de la mort du processus de contrôle.
   // Sous certains systèmes (Linux...), la mort du terminal de contrôle
   // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
   // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
   // non initialisée (pointeur NULL) issue de TERMIO.
   
   void
   interruption2(int signal)
   {
       unsigned char       signal_tronque;
   
       test_signal(signal);
   
       signal_tronque = (unsigned char) (rpl_sigtstp & 0xFF);
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
       write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
   
   #   pragma GCC diagnostic pop
   
       return;
   }
   
   void
   interruption3(int signal)
   {
       // Si on passe par ici, c'est qu'il est impossible de récupérer
       // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
       // ce qu'il reste des processus orphelins.
   
       unsigned char       message_1[] = "+++System : Uncaught access violation\n"
                                   "+++System : Aborting !\n";
       unsigned char       message_2[] = "+++System : Stack overflow\n"
                                   "+++System : Aborting !\n";
   
       test_signal(signal);
   
       if (pid_processus_pere == getpid())
       {
           kill(pid_processus_pere, SIGUSR1);
       }
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
       if (signal != SIGUSR2)
       {
           write(STDERR_FILENO, message_1, strlen(message_1));
       }
       else
       {
           write(STDERR_FILENO, message_2, strlen(message_2));
       }
   
   #   pragma GCC diagnostic pop
   
       _exit(EXIT_FAILURE);
   }
   
   // Récupération des signaux
   // - SIGHUP
   
   void
   interruption4(int signal)
   {
       unsigned char       signal_tronque;
   
       test_signal(signal);
   
       signal_tronque = (unsigned char) (rpl_sighup & 0xFF);
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
       write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
   
   #   pragma GCC diagnostic pop
   
       return;
   }
   
   // Récupération des signaux
   // - SIGPIPE
   
   void
   interruption5(int signal)
   {
       unsigned char       message[] = "+++System : SIGPIPE\n"
                                   "+++System : Aborting !\n";
       unsigned char       signal_tronque;
   
       test_signal(signal);
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
       if (pid_processus_pere == getpid())
       {
           signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);
           write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
       }
   
       write(STDERR_FILENO, message, strlen(message));
   
   #   pragma GCC diagnostic pop
   
     return;      return;
 }  }
   
Line 1817  signal_int(struct_processus *s_etat_proc Line 1940  signal_int(struct_processus *s_etat_proc
     return;      return;
 }  }
   
 // Récupération des signaux  
 // - SIGFSTP  
 //  
 // ATTENTION :  
 // Le signal SIGFSTP provient de la mort du processus de contrôle.  
 // Sous certains systèmes (Linux...), la mort du terminal de contrôle  
 // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres  
 // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo  
 // non initialisée (pointeur NULL) issue de TERMIO.  
   
 void  
 interruption2(int signal)  
 {  
     test_signal(signal);  
     envoi_signal_processus(getpid(), rpl_sigtstp);  
     return;  
 }  
   
 static inline void  static inline void
 signal_tstp(struct_processus *s_etat_processus, pid_t pid)  signal_tstp(struct_processus *s_etat_processus, pid_t pid)
 {  {
Line 1882  signal_tstp(struct_processus *s_etat_pro Line 1987  signal_tstp(struct_processus *s_etat_pro
     return;      return;
 }  }
   
 void  
 interruption3(int signal)  
 {  
     // Si on passe par ici, c'est qu'il est impossible de récupérer  
     // l'erreur d'accès à la mémoire. On sort donc du programme quitte à  
     // ce qu'il reste des processus orphelins.  
   
     unsigned char       message_1[] = "+++System : Uncaught access violation\n"  
                                 "+++System : Aborting !\n";  
     unsigned char       message_2[] = "+++System : Stack overflow\n"  
                                 "+++System : Aborting !\n";  
   
     test_signal(signal);  
   
     if (pid_processus_pere == getpid())  
     {  
         kill(pid_processus_pere, SIGUSR1);  
     }  
   
     if (signal != SIGUSR2)  
     {  
         write(STDERR_FILENO, message_1, strlen(message_1));  
     }  
     else  
     {  
         write(STDERR_FILENO, message_2, strlen(message_2));  
     }  
   
     _exit(EXIT_FAILURE);  
 }  
   
   
 static void  static void
 sortie_interruption_depassement_pile(void *arg1, void *arg2, void *arg3)  sortie_interruption_depassement_pile(void *arg1, void *arg2, void *arg3)
 {  {
Line 1931  sortie_interruption_depassement_pile(voi Line 2004  sortie_interruption_depassement_pile(voi
     return;      return;
 }  }
   
   
 void  void
 interruption_depassement_pile(int urgence, stackoverflow_context_t scp)  interruption_depassement_pile(int urgence, stackoverflow_context_t scp)
 {  {
Line 1949  interruption_depassement_pile(int urgenc Line 2021  interruption_depassement_pile(int urgenc
     return;      return;
 }  }
   
   
 int  int
 interruption_violation_access(void *adresse_fautive, int gravite)  interruption_violation_access(void *adresse_fautive, int gravite)
 {  {
Line 1978  interruption_violation_access(void *adre Line 2049  interruption_violation_access(void *adre
         return(0);          return(0);
     }      }
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
     write(STDERR_FILENO, message, strlen(message));      write(STDERR_FILENO, message, strlen(message));
   
   #   pragma GCC diagnostic pop
   
     if (pid_processus_pere == getpid())      if (pid_processus_pere == getpid())
     {      {
         longjmp(contexte_initial, -1);          longjmp(contexte_initial, -1);
Line 2125  signal_inject(struct_processus *s_etat_p Line 2201  signal_inject(struct_processus *s_etat_p
     return;      return;
 }  }
   
 // Récupération des signaux  
 // - SIGPIPE  
   
 void  
 interruption5(int signal)  
 {  
     unsigned char       message[] = "+++System : SIGPIPE\n"  
                                 "+++System : Aborting !\n";  
   
     test_signal(signal);  
   
     if (pid_processus_pere == getpid())  
     {  
         envoi_signal_processus(pid_processus_pere, rpl_sigalrm);  
     }  
   
     write(STDERR_FILENO, message, strlen(message));  
     return;  
 }  
   
 static inline void  static inline void
 signal_urg(struct_processus *s_etat_processus, pid_t pid)  signal_urg(struct_processus *s_etat_processus, pid_t pid)
Line 2238  signal_abort(struct_processus *s_etat_pr Line 2295  signal_abort(struct_processus *s_etat_pr
     return;      return;
 }  }
   
 // Récupération des signaux  
 // - SIGHUP  
   
 void  
 interruption4(int signal)  
 {  
     test_signal(signal);  
     envoi_signal_processus(getpid(), rpl_sighup);  
     return;  
 }  
   
 static inline void  static inline void
 signal_hup(struct_processus *s_etat_processus, pid_t pid)  signal_hup(struct_processus *s_etat_processus, pid_t pid)
Line 2264  signal_hup(struct_processus *s_etat_proc Line 2311  signal_hup(struct_processus *s_etat_proc
         return;          return;
     }      }
   
     snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),      snprintf(nom, 8 + 64 + 1, "rpl-out-%llu-%llu",
             (unsigned long) pthread_self());              (unsigned long long) getpid(),
               (unsigned long long) pthread_self());
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
     if ((fichier = fopen(nom, "w+")) != NULL)      if ((fichier = fopen(nom, "w+")) != NULL)
     {      {
Line 2277  signal_hup(struct_processus *s_etat_proc Line 2328  signal_hup(struct_processus *s_etat_proc
   
     freopen("/dev/null", "r", stdin);      freopen("/dev/null", "r", stdin);
   
   #   pragma GCC diagnostic pop
   
     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)      if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
     {      {
         printf("[%d] RPL/SIGHUP (thread %llu)\n", (int) getpid(),          printf("[%d] RPL/SIGHUP (thread %llu)\n", (int) getpid(),
Line 2374  envoi_interruptions(struct_processus *s_ Line 2427  envoi_interruptions(struct_processus *s_
         default:          default:
             if ((*s_etat_processus).langue == 'F')              if ((*s_etat_processus).langue == 'F')
             {              {
                 printf("+++System : Spurious signal (%d) !\n", signal);                  printf("+++System : Signal inconnu (%d) !\n", signal);
             }              }
             else              else
             {              {
                 printf("+++System : Signal inconnu (%d) !\n", signal);                  printf("+++System : Spurious signal (%d) !\n", signal);
             }              }
   
             break;              break;
Line 2397  scrutation_interruptions(struct_processu Line 2450  scrutation_interruptions(struct_processu
     // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à      // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à
     // écrire.      // écrire.
   
 #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)      if (sem_trywait(semaphore_queue_signaux) == 0)
         if (sem_trywait(&((*s_queue_signaux).semaphore)) == 0)  
 #   else  
         if (sem_trywait(semaphore_queue_signaux) == 0)  
 #   endif  
     {      {
         while((*s_queue_signaux).pointeur_lecture !=          while((*s_queue_signaux).pointeur_lecture !=
                 (*s_queue_signaux).pointeur_ecriture)                  (*s_queue_signaux).pointeur_ecriture)
Line 2417  scrutation_interruptions(struct_processu Line 2466  scrutation_interruptions(struct_processu
                     ((*s_queue_signaux).pointeur_lecture + 1)                      ((*s_queue_signaux).pointeur_lecture + 1)
                     % LONGUEUR_QUEUE_SIGNAUX;                      % LONGUEUR_QUEUE_SIGNAUX;
   
 #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)  #           ifndef IPCS_SYSV
             sem_wait(&((*s_queue_signaux).signalisation));              if (msync(s_queue_signaux, sizeof(s_queue_signaux),
 #           else                      MS_ASYNC | MS_INVALIDATE) != 0)
             sem_wait(semaphore_signalisation);              {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
 #           endif  #           endif
   
               while(sem_wait(semaphore_signalisation) != 0)
               {
                   if (errno != EINTR)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                       return;
                   }
               }
         }          }
   
 #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)          sem_post(semaphore_queue_signaux);
             sem_post(&((*s_queue_signaux).semaphore));  
 #       else  
             sem_post(semaphore_queue_signaux);  
 #       endif  
     }      }
   
     // Interruptions qui arrivent depuis le groupe courant de threads.      // Interruptions qui arrivent depuis le groupe courant de threads.
   
     if (pthread_mutex_trylock(&mutex_interruptions) == 0)      if (pthread_mutex_trylock(&((*s_etat_processus).mutex_signaux)) == 0)
     {      {
         while((*s_etat_processus).pointeur_signal_lecture !=          while((*s_etat_processus).pointeur_signal_lecture !=
                 (*s_etat_processus).pointeur_signal_ecriture)                  (*s_etat_processus).pointeur_signal_ecriture)
Line 2448  scrutation_interruptions(struct_processu Line 2505  scrutation_interruptions(struct_processu
                     ((*s_etat_processus).pointeur_signal_lecture + 1)                      ((*s_etat_processus).pointeur_signal_lecture + 1)
                     % LONGUEUR_QUEUE_SIGNAUX;                      % LONGUEUR_QUEUE_SIGNAUX;
   
 #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)              while(sem_wait(semaphore_signalisation) != 0)
             sem_wait(&((*s_queue_signaux).signalisation));              {
 #           else                  if (errno != EINTR)
             sem_wait(semaphore_signalisation);                  {
 #           endif                      (*s_etat_processus).erreur_systeme = d_es_processus;
                       return;
                   }
               }
         }          }
   
         pthread_mutex_unlock(&mutex_interruptions);          pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux));
     }      }
   
     return;      return;
 }  }
   
   
 /*  /*
 ================================================================================  ================================================================================
   Fonction renvoyant le nom du segment de mémoire partagée en fonction    Fonction renvoyant le nom du segment de mémoire partagée en fonction
Line 2533  envoi_signal_processus(pid_t pid, enum s Line 2594  envoi_signal_processus(pid_t pid, enum s
 #   endif  #   endif
   
 #   ifndef IPCS_SYSV  #   ifndef IPCS_SYSV
 #       ifdef SEMAPHORES_NOMMES          sem_t                       *semaphore;
             sem_t                   *semaphore;          sem_t                       *signalisation;
             sem_t                   *signalisation;  
 #       endif  
 #   else  #   else
           sem_t                       *semaphore;
           sem_t                       *signalisation;
 #       ifndef OS2  #       ifndef OS2
             int                     desc;              int                     desc;
             key_t                   clef;              key_t                   clef;
Line 2560  envoi_signal_processus(pid_t pid, enum s Line 2621  envoi_signal_processus(pid_t pid, enum s
             return(1);              return(1);
         }          }
   
 #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)          while(sem_wait(semaphore_queue_signaux) != 0)
             while(sem_wait(&((*s_queue_signaux).semaphore)) != 0)  
 #       else  
             while(sem_wait(semaphore_queue_signaux) != 0)  
 #       endif  
         {          {
             if (errno != EINTR)              if (errno != EINTR)
             {              {
Line 2581  envoi_signal_processus(pid_t pid, enum s Line 2638  envoi_signal_processus(pid_t pid, enum s
                 ((*s_queue_signaux).pointeur_ecriture + 1)                  ((*s_queue_signaux).pointeur_ecriture + 1)
                 % LONGUEUR_QUEUE_SIGNAUX;                  % LONGUEUR_QUEUE_SIGNAUX;
   
 #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)  #       ifndef IPCS_SYSV
             if (sem_post(&((*s_queue_signaux).semaphore)) != 0)          if (msync(s_queue_signaux, sizeof(s_queue_signaux),
 #       else                  MS_ASYNC | MS_INVALIDATE) != 0)
             if (sem_post(semaphore_queue_signaux) != 0)          {
               return(1);
           }
 #       endif  #       endif
   
           if (sem_post(semaphore_queue_signaux) != 0)
         {          {
             return(1);              return(1);
         }          }
   
 #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)          if (sem_post(semaphore_signalisation) != 0)
             if (sem_post(&((*s_queue_signaux).signalisation)) != 0)  
 #       else  
             if (sem_post(semaphore_signalisation) != 0)  
 #       endif  
         {          {
             return(1);              return(1);
         }          }
Line 2666  envoi_signal_processus(pid_t pid, enum s Line 2723  envoi_signal_processus(pid_t pid, enum s
             }              }
 #       endif  #       endif
   
             // À ce moment, le segment de mémoire partagée est projeté          // À ce moment, le segment de mémoire partagée est projeté
             // dans l'espace du processus.          // dans l'espace du processus.
   
 #       ifndef IPCS_SYSV // POSIX          if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)
 #           ifndef SEMAPHORES_NOMMES          {
                 while(sem_wait(&((*queue).semaphore)) != 0)              return(1);
                 {          }
                     if (errno != EINTR)  
                     {  
                         return(1);  
                     }  
                 }  
 #           else  
                 if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)  
                 {  
                     return(1);  
                 }  
   
                 if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))          if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))
                         == SEM_FAILED)                  == SEM_FAILED)
                 {          {
                     return(1);              return(1);
                 }          }
   
                 while(sem_wait(semaphore) != 0)          while(sem_wait(semaphore) != 0)
                 {          {
                     if (errno != EINTR)              if (errno != EINTR)
                     {  
                         sem_close(semaphore);  
                         sem_close(signalisation);  
                         return(1);  
                     }  
                 }  
 #           endif  
 #       else // IPCS_SYSV  
             while(sem_wait(&((*queue).semaphore)) != 0)  
             {              {
                 if (errno != EINTR)                  sem_close(semaphore);
                 {                  sem_close(signalisation);
                     return(1);                  return(1);
                 }  
             }              }
 #       endif          }
   
         (*queue).queue[(*queue).pointeur_ecriture].pid = getpid();          (*queue).queue[(*queue).pointeur_ecriture].pid = getpid();
         (*queue).queue[(*queue).pointeur_ecriture].signal = signal;          (*queue).queue[(*queue).pointeur_ecriture].signal = signal;
Line 2716  envoi_signal_processus(pid_t pid, enum s Line 2753  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 // POSIX  #       ifndef IPCS_SYSV
 #           ifndef SEMAPHORES_NOMMES          if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                 if (sem_post(&((*queue).semaphore)) != 0)          {
                 {              sem_close(semaphore);
                     return(1);              sem_close(signalisation);
                 }              return(1);
           }
                 if (sem_post(&((*queue).signalisation)) != 0)  #       endif
                 {  
                     return(1);  
                 }  
 #           else  
                 if (sem_post(semaphore) != 0)  
                 {  
                     sem_close(semaphore);  
                     sem_close(signalisation);  
                     return(1);  
                 }  
   
                 if (sem_close(semaphore) != 0)          if (sem_post(semaphore) != 0)
                 {          {
                     return(1);              sem_close(semaphore);
                 }              sem_close(signalisation);
               return(1);
           }
   
                 if (sem_post(signalisation) != 0)          if (sem_close(semaphore) != 0)
                 {          {
                     sem_close(signalisation);              return(1);
                     return(1);          }
                 }  
   
                 if (sem_close(signalisation) != 0)          if (sem_post(signalisation) != 0)
                 {          {
                     return(1);              sem_close(signalisation);
                 }              return(1);
           }
   
 #           endif          if (sem_close(signalisation) != 0)
           {
               return(1);
           }
   
   #       ifndef IPCS_SYSV // POSIX
             if (munmap(queue, sizeof(struct_queue_signaux)) != 0)              if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
             {              {
                 close(segment);                  close(segment);
                 return(1);                  return(1);
             }              }
 #       else // IPCS_SYSV  #       else // IPCS_SYSV
             if (sem_post(&((*queue).semaphore)) != 0)  
             {  
                 return(1);  
             }  
   
             if (sem_post(&((*queue).signalisation)) != 0)  
             {  
                 return(1);  
             }  
   
 #           ifndef OS2 // SysV  #           ifndef OS2 // SysV
                 if (shmdt(queue) != 0)                  if (shmdt(queue) != 0)
                 {                  {
Line 2817  envoi_signal_thread(pthread_t tid, enum Line 2840  envoi_signal_thread(pthread_t tid, enum
         return(1);          return(1);
     }      }
   
     if (pthread_mutex_lock(&mutex_interruptions) != 0)      s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
               .s_etat_processus;
   
       if (pthread_mutex_lock(&((*s_etat_processus).mutex_signaux)) != 0)
     {      {
         pthread_mutex_unlock(&mutex_liste_threads);          pthread_mutex_unlock(&mutex_liste_threads);
         return(1);          return(1);
     }      }
   
     s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))  
             .s_etat_processus;  
   
     (*s_etat_processus).signaux_en_queue      (*s_etat_processus).signaux_en_queue
             [(*s_etat_processus).pointeur_signal_ecriture] = signal;              [(*s_etat_processus).pointeur_signal_ecriture] = signal;
     (*s_etat_processus).pointeur_signal_ecriture =      (*s_etat_processus).pointeur_signal_ecriture =
             ((*s_etat_processus).pointeur_signal_ecriture + 1)              ((*s_etat_processus).pointeur_signal_ecriture + 1)
             % LONGUEUR_QUEUE_SIGNAUX;              % LONGUEUR_QUEUE_SIGNAUX;
   
     if (pthread_mutex_unlock(&mutex_interruptions) != 0)      if (pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux)) != 0)
     {      {
         pthread_mutex_unlock(&mutex_liste_threads);          pthread_mutex_unlock(&mutex_liste_threads);
         return(1);          return(1);
Line 2843  envoi_signal_thread(pthread_t tid, enum Line 2866  envoi_signal_thread(pthread_t tid, enum
         return(1);          return(1);
     }      }
   
 #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)  
     if (sem_post(&((*s_queue_signaux).signalisation)) != 0)  
     {  
         return(1);  
     }  
 #   else  
     if (sem_post(semaphore_signalisation) != 0)      if (sem_post(semaphore_signalisation) != 0)
     {      {
         return(1);          return(1);
     }      }
 #   endif  
   
     return(0);      return(0);
 }  }
Line 2862  int Line 2878  int
 envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,  envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
         enum signaux_rpl signal)          enum signaux_rpl signal)
 {  {
     pthread_mutex_lock(&mutex_interruptions);      pthread_mutex_lock(&((*s_etat_processus_a_signaler).mutex_signaux));
     (*s_etat_processus_a_signaler).signaux_en_queue      (*s_etat_processus_a_signaler).signaux_en_queue
             [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =              [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =
             signal;              signal;
     (*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_mutex_unlock(&mutex_interruptions);      pthread_mutex_unlock(&((*s_etat_processus_a_signaler).mutex_signaux));
   
 #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)  
     if (sem_post(&((*s_queue_signaux).signalisation)) != 0)  
     {  
         return(1);  
     }  
 #   else  
     if (sem_post(semaphore_signalisation) != 0)      if (sem_post(semaphore_signalisation) != 0)
     {      {
         return(1);          return(1);
     }      }
 #   endif  
   
     return(0);      return(0);
 }  }
Line 2951  creation_queue_signaux(struct_processus Line 2960  creation_queue_signaux(struct_processus
   
         free(nom);          free(nom);
   
 #       ifndef SEMAPHORES_NOMMES          if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
             sem_init(&((*s_queue_signaux).semaphore), 1, 1);                  == SEM_FAILED)
             sem_init(&((*s_queue_signaux).signalisation), 1, 0);          {
 #       else              (*s_etat_processus).erreur_systeme = d_es_processus;
             if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))              return;
                     == SEM_FAILED)          }
             {  
                 (*s_etat_processus).erreur_systeme = d_es_processus;  
                 return;  
             }  
   
             if ((semaphore_signalisation = sem_init2(1, getpid(),          if ((semaphore_signalisation = sem_init2(0, getpid(),
                     SEM_SIGNALISATION)) == SEM_FAILED)                  SEM_SIGNALISATION)) == SEM_FAILED)
             {          {
                 (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
                 return;              return;
             }          }
 #       endif  
           if ((semaphore_arret_signalisation = sem_init2(1, getpid(),
                   SEM_ARRET_SIGNALISATION)) == SEM_FAILED)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               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;
   
         (*s_queue_signaux).requete_arret = d_faux;          (*s_queue_signaux).requete_arret = d_faux;
   
         if (msync(s_queue_signaux, sizeof(struct_queue_signaux), 0))          if (msync(s_queue_signaux, sizeof(struct_queue_signaux), MS_SYNC))
         {          {
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
             return;              return;
Line 3035  creation_queue_signaux(struct_processus Line 3047  creation_queue_signaux(struct_processus
                 return;                  return;
             }              }
   
             sem_init(&((*s_queue_signaux).semaphore), 1, 1);              if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
             sem_init(&((*s_queue_signaux).signalisation), 1, 0);                      == SEM_FAILED)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               if ((semaphore_signalisation = sem_init2(0, getpid(),
                       SEM_SIGNALISATION)) == SEM_FAILED)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               if ((semaphore_arret_signalisation = sem_init2(1, getpid(),
                       SEM_ARRET_SIGNALISATION)) == SEM_FAILED)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   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;
             (*s_queue_signaux).requete_arret = d_faux;              (*s_queue_signaux).requete_arret = d_faux;
Line 3060  creation_queue_signaux(struct_processus Line 3091  creation_queue_signaux(struct_processus
   
             sem_init(&((*s_queue_signaux).semaphore), 1, 1);              sem_init(&((*s_queue_signaux).semaphore), 1, 1);
             sem_init(&((*s_queue_signaux).signalisation), 1, 0);              sem_init(&((*s_queue_signaux).signalisation), 1, 0);
               sem_init(&((*s_queue_signaux).arret_signalisation), 1, 1);
   
             (*s_queue_signaux).pointeur_lecture = 0;              (*s_queue_signaux).pointeur_lecture = 0;
             (*s_queue_signaux).pointeur_ecriture = 0;              (*s_queue_signaux).pointeur_ecriture = 0;
             (*s_queue_signaux).requete_arret = d_faux;              (*s_queue_signaux).requete_arret = d_faux;
Line 3138  creation_queue_signaux(struct_processus Line 3171  creation_queue_signaux(struct_processus
 void  void
 liberation_queue_signaux(struct_processus *s_etat_processus)  liberation_queue_signaux(struct_processus *s_etat_processus)
 {  {
     // Incrémenter le sémaphore pour être sûr de le débloquer.      sem_wait(semaphore_arret_signalisation);
   
     (*s_queue_signaux).requete_arret = d_vrai;      (*s_queue_signaux).requete_arret = d_vrai;
   
 #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)  #   ifndef IPCS_SYSV
     sem_post(&((*s_queue_signaux).signalisation));      msync(s_queue_signaux, sizeof(s_queue_signaux), MS_ASYNC | MS_INVALIDATE);
 #   else  
     sem_post(semaphore_signalisation);  
 #   endif  #   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);      pthread_join((*s_queue_signaux).thread_signaux, NULL);
   
 #   ifdef IPCS_SYSV // SystemV  #   ifdef IPCS_SYSV // SystemV
Line 3160  liberation_queue_signaux(struct_processu Line 3195  liberation_queue_signaux(struct_processu
 #       else // OS/2  #       else // OS/2
 #       endif  #       endif
 #   else // POSIX  #   else // POSIX
 #       ifndef SEMAPHORES_NOMMES          sem_close(semaphore_queue_signaux);
             sem_close(&((*s_queue_signaux).semaphore));          sem_close(semaphore_signalisation);
             sem_close(&((*s_queue_signaux).signalisation));          sem_close(semaphore_arret_signalisation);
 #       else  
             sem_close(semaphore_queue_signaux);  
             sem_close(semaphore_signalisation);  
 #       endif  
   
         if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)          if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
         {          {
Line 3201  destruction_queue_signaux(struct_process Line 3232  destruction_queue_signaux(struct_process
         unsigned char       *nom;          unsigned char       *nom;
 #   endif  #   endif
   
     // Incrémenter le sémaphore pour être sûr de le débloquer.      sem_wait(semaphore_arret_signalisation);
   
     (*s_queue_signaux).requete_arret = d_vrai;      (*s_queue_signaux).requete_arret = d_vrai;
   
 #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)  #   ifndef IPCS_SYSV
     sem_post(&((*s_queue_signaux).signalisation));      msync(s_queue_signaux, sizeof(s_queue_signaux), MS_ASYNC | MS_INVALIDATE);
 #   else  
     sem_post(semaphore_signalisation);  
 #   endif  #   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);      pthread_join((*s_queue_signaux).thread_signaux, NULL);
   
 #   ifdef IPCS_SYSV // SystemV  #   ifdef IPCS_SYSV // SystemV
 #       ifndef OS2  #       ifndef OS2
             // Il faut commencer par éliminer le sémaphore.              // Il faut commencer par éliminer le sémaphore.
   
             if (semctl((*s_queue_signaux).semaphore.sem, 0, IPC_RMID) == -1)              if (semctl((*semaphore_queue_signaux).sem, 0, IPC_RMID) == -1)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               unlink((*semaphore_queue_signaux).path);
               free((*semaphore_queue_signaux).path);
   
               if (semctl((*semaphore_signalisation).sem, 0, IPC_RMID) == -1)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                 return;                  return;
             }              }
   
             unlink((*s_queue_signaux).semaphore.path);              unlink((*semaphore_signalisation).path);
             free((*s_queue_signaux).semaphore.path);              free((*semaphore_signalisation).path);
   
             if (semctl((*s_queue_signaux).signalisation.sem, 0, IPC_RMID) == -1)              if (semctl((*semaphore_arret_signalisation).sem, 0, IPC_RMID) == -1)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                 return;                  return;
             }              }
   
             unlink((*s_queue_signaux).signalisation.path);              unlink((*semaphore_arret_signalisation).path);
             free((*s_queue_signaux).signalisation.path);              free((*semaphore_arret_signalisation).path);
   
             if (shmdt(s_queue_signaux) == -1)              if (shmdt(s_queue_signaux) == -1)
             {              {
Line 3263  destruction_queue_signaux(struct_process Line 3306  destruction_queue_signaux(struct_process
             sem_close(&((*s_queue_signaux).signalisation));              sem_close(&((*s_queue_signaux).signalisation));
             sem_destroy(&((*s_queue_signaux).signalisation));              sem_destroy(&((*s_queue_signaux).signalisation));
   
               sem_close(&((*s_queue_signaux).arret_signalisation));
               sem_destroy(&((*s_queue_signaux).arret_signalisation));
   
             if (DosFreeMem(s_queue_signaux) != 0)              if (DosFreeMem(s_queue_signaux) != 0)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;                  (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
Line 3270  destruction_queue_signaux(struct_process Line 3316  destruction_queue_signaux(struct_process
             }              }
 #       endif  #       endif
 #   else // POSIX  #   else // POSIX
 #       ifndef SEMAPHORES_NOMMES          sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);
             sem_close(&((*s_queue_signaux).semaphore));          sem_destroy2(semaphore_signalisation, getpid(), SEM_SIGNALISATION);
             sem_destroy(&((*s_queue_signaux).semaphore));          sem_destroy2(semaphore_arret_signalisation, getpid(),
                   SEM_ARRET_SIGNALISATION);
             sem_close(&((*s_queue_signaux).signalisation));  
             sem_destroy(&((*s_queue_signaux).signalisation));  
 #       else  
             sem_close(semaphore_queue_signaux);  
             sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);  
   
             sem_close(semaphore_signalisation);  
             sem_destroy2(semaphore_signalisation, getpid(), SEM_SIGNALISATION);  
 #       endif  
   
         if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)          if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
         {          {

Removed from v.1.101  
changed lines
  Added in v.1.152


CVSweb interface <joel.bertrand@systella.fr>