Diff for /rpl/src/interruptions.c between versions 1.96 and 1.137

version 1.96, 2012/05/17 17:06:18 version 1.137, 2013/09/06 10:30:56
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.8    RPL/2 (R) version 4.1.16
   Copyright (C) 1989-2012 Dr. BERTRAND Joël    Copyright (C) 1989-2013 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;
   
 #       ifndef SEMAPHORES_NOMMES  #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
         if (sem_wait(&(*s_queue_signaux).signalisation) == 0)          if (sem_wait(&(*s_queue_signaux).signalisation) == 0)
 #       else  #       else
         if(sem_wait(semaphore_signalisation) == 0)          if (sem_wait(semaphore_signalisation) == 0)
 #       endif  #       endif
         {          {
   #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
               if (sem_wait(&(*s_queue_signaux).arret_signalisation) != 0)
   #           else
               if (sem_wait(semaphore_arret_signalisation) != 0)
   #           endif
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
               }
   
             if ((*s_queue_signaux).requete_arret == d_vrai)              if ((*s_queue_signaux).requete_arret == d_vrai)
             {              {
   #               if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
                   sem_post(&(*s_queue_signaux).arret_signalisation);
                   sem_post(&(*s_queue_signaux).signalisation);
   #               else
                   sem_post(semaphore_arret_signalisation);
                   sem_post(semaphore_signalisation);
   #               endif
   
                 break;                  break;
             }              }
   
   #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
               sem_post(&(*s_queue_signaux).arret_signalisation);
               sem_post(&(*s_queue_signaux).signalisation);
   #           else
               sem_post(semaphore_arret_signalisation);
               sem_post(semaphore_signalisation);
   #           endif
   
             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.
   
 #           ifndef SEMAPHORES_NOMMES  #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
             sem_wait(&(*s_queue_signaux).semaphore);              sem_wait(&(*s_queue_signaux).semaphore);
 #           else  #           else
             sem_wait(semaphore_queue_signaux);              sem_wait(semaphore_queue_signaux);
Line 114  thread_surveillance_signaux(void *argume Line 142  thread_surveillance_signaux(void *argume
             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);
             }              }
   
 #           ifndef SEMAPHORES_NOMMES  #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
             sem_post(&(*s_queue_signaux).semaphore);              sem_post(&(*s_queue_signaux).semaphore);
 #           else  #           else
             sem_post(semaphore_queue_signaux);              sem_post(semaphore_queue_signaux);
Line 127  thread_surveillance_signaux(void *argume Line 161  thread_surveillance_signaux(void *argume
             // 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 135  thread_surveillance_signaux(void *argume Line 173  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 160  thread_surveillance_signaux(void *argume Line 207  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 310  retrait_thread(struct_processus *s_etat_ Line 360  retrait_thread(struct_processus *s_etat_
         return;          return;
     }      }
   
       // Le thread ne peut plus traiter de signaux explicites. Il convient
       // alors de corriger le sémaphore pour annuler les signaux en attente.
   
       while((*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus)
               .pointeur_signal_ecriture != (*(*((struct_thread *)
               (*l_element_courant).donnee)).s_etat_processus)
               .pointeur_signal_lecture)
       {
   #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
           while(sem_wait(&((*s_queue_signaux).signalisation)) != 0)
   #       else
           while(sem_wait(semaphore_signalisation) != 0)
   #       endif
           {
               if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
           }
   
           (*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus)
                   .pointeur_signal_lecture = ((*(*((struct_thread *)
                   (*l_element_courant).donnee)).s_etat_processus)
                   .pointeur_signal_lecture + 1) % LONGUEUR_QUEUE_SIGNAUX;
       }
   
     free((void *) (*l_element_courant).donnee);      free((void *) (*l_element_courant).donnee);
     free((struct_liste_chainee_volatile *) l_element_courant);      free((struct_liste_chainee_volatile *) l_element_courant);
   
Line 501  liberation_threads(struct_processus *s_e Line 578  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 544  liberation_threads(struct_processus *s_e Line 627  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 613  liberation_threads(struct_processus *s_e Line 695  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 716  liberation_threads(struct_processus *s_e Line 796  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 1274  liberation_threads(struct_processus *s_e Line 1337  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 1334  recherche_thread(pid_t pid, pthread_t ti Line 1396  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 1354  recherche_thread(pid_t pid, pthread_t ti Line 1421  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 1415  recherche_thread_principal(pid_t pid) Line 1488  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 1427  verrouillage_gestionnaire_signaux(struct Line 1498  verrouillage_gestionnaire_signaux(struct
         return;          return;
     }      }
   
     // Il faut respecteur l'atomicité des deux opérations suivantes !  
   
     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  #   ifndef SEMAPHORES_NOMMES
     if (sem_post(&semaphore_gestionnaires_signaux) == -1)      if (sem_post(&semaphore_gestionnaires_signaux) == -1)
 #   else  #   else
Line 1455  verrouillage_gestionnaire_signaux(struct Line 1513  verrouillage_gestionnaire_signaux(struct
         return;          return;
     }      }
   
       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 1504  verrouillage_gestionnaire_signaux(struct Line 1535  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]);
   
     if (semaphore == 1)      return(d_absence_erreur);
   }
   
   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;          read(fds.fd, &signal, 1);
 }  
   
 #define test_signal(signal) \          if (signal != (0xFF & rpl_sigmax))
     if (signal_test == SIGTEST) { signal_test = signal; return; }          {
               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)
 // - SIGTERM (signal d'arrêt en provenance du système)  // - SIGTERM (signal d'arrêt en provenance du système)
   
 void  void
 interruption1(int signal)  interruption1(int signal)
 {  {
       unsigned char       signal_tronque;
   
     test_signal(signal);      test_signal(signal);
   
     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;
     }      }
   
     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)
   {
       unsigned char       signal_tronque;
   
       test_signal(signal);
   
       signal_tronque = (unsigned char) (rpl_sigtstp & 0xFF);
       write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
       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);
   }
   
   // Récupération des signaux
   // - SIGHUP
   
   void
   interruption4(int signal)
   {
       unsigned char       signal_tronque;
   
       test_signal(signal);
   
       signal_tronque = (unsigned char) (rpl_sighup & 0xFF);
       write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
       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);
   
       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));
       return;
   }
   
 inline static void  inline static void
 signal_alrm(struct_processus *s_etat_processus, pid_t pid)  signal_alrm(struct_processus *s_etat_processus, pid_t pid)
 {  {
Line 1674  inline static void Line 1834  inline static void
 signal_term(struct_processus *s_etat_processus, pid_t pid)  signal_term(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 1696  signal_term(struct_processus *s_etat_pro Line 1856  signal_term(struct_processus *s_etat_pro
         {          {
             (*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;
             }              }
   
             (*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 1791  signal_int(struct_processus *s_etat_proc Line 1950  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 1856  signal_tstp(struct_processus *s_etat_pro Line 1997  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 1905  sortie_interruption_depassement_pile(voi Line 2014  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 1923  interruption_depassement_pile(int urgenc Line 2031  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 2099  signal_inject(struct_processus *s_etat_p Line 2206  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 2212  signal_abort(struct_processus *s_etat_pr Line 2300  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 2238  signal_hup(struct_processus *s_etat_proc Line 2316  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());
   
     if ((fichier = fopen(nom, "w+")) != NULL)      if ((fichier = fopen(nom, "w+")) != NULL)
     {      {
Line 2348  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 2371  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.
   
 #   ifndef SEMAPHORES_NOMMES  #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
         if (sem_trywait(&((*s_queue_signaux).semaphore)) == 0)          if (sem_trywait(&((*s_queue_signaux).semaphore)) == 0)
 #   else  #   else
         if (sem_trywait(semaphore_queue_signaux) == 0)          if (sem_trywait(semaphore_queue_signaux) == 0)
Line 2391  scrutation_interruptions(struct_processu Line 2470  scrutation_interruptions(struct_processu
                     ((*s_queue_signaux).pointeur_lecture + 1)                      ((*s_queue_signaux).pointeur_lecture + 1)
                     % LONGUEUR_QUEUE_SIGNAUX;                      % LONGUEUR_QUEUE_SIGNAUX;
   
 #           ifndef SEMAPHORES_NOMMES  #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
             sem_wait(&((*s_queue_signaux).signalisation));              while(sem_wait(&((*s_queue_signaux).signalisation)) != 0)
 #           else  #           else
             sem_wait(semaphore_signalisation);              while(sem_wait(semaphore_signalisation) != 0)
 #           endif  #           endif
               {
                   if (errno != EINTR)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                       return;
                   }
               }
         }          }
   
 #       ifndef SEMAPHORES_NOMMES  #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
             sem_post(&((*s_queue_signaux).semaphore));              sem_post(&((*s_queue_signaux).semaphore));
 #       else  #       else
             sem_post(semaphore_queue_signaux);              sem_post(semaphore_queue_signaux);
Line 2407  scrutation_interruptions(struct_processu Line 2493  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(&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 2422  scrutation_interruptions(struct_processu Line 2508  scrutation_interruptions(struct_processu
                     ((*s_etat_processus).pointeur_signal_lecture + 1)                      ((*s_etat_processus).pointeur_signal_lecture + 1)
                     % LONGUEUR_QUEUE_SIGNAUX;                      % LONGUEUR_QUEUE_SIGNAUX;
   
 #           ifndef SEMAPHORES_NOMMES  #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
             sem_wait(&((*s_queue_signaux).signalisation));              while(sem_wait(&((*s_queue_signaux).signalisation)) != 0)
 #           else  #           else
             sem_wait(semaphore_signalisation);              while(sem_wait(semaphore_signalisation) != 0)
 #           endif  #           endif
               {
                   if (errno != EINTR)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                       return;
                   }
               }
         }          }
   
         pthread_mutex_unlock(&mutex_interruptions);          pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux));
     }      }
   
     return;      return;
Line 2509  envoi_signal_processus(pid_t pid, enum s Line 2602  envoi_signal_processus(pid_t pid, enum s
 #   ifndef IPCS_SYSV  #   ifndef IPCS_SYSV
 #       ifdef SEMAPHORES_NOMMES  #       ifdef SEMAPHORES_NOMMES
             sem_t                   *semaphore;              sem_t                   *semaphore;
               sem_t                   *signalisation;
 #       endif  #       endif
 #   else  #   else
 #       ifndef OS2  #       ifndef OS2
Line 2533  envoi_signal_processus(pid_t pid, enum s Line 2627  envoi_signal_processus(pid_t pid, enum s
             return(1);              return(1);
         }          }
   
 #       ifndef SEMAPHORES_NOMMES  #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
             while(sem_wait(&((*s_queue_signaux).semaphore)) != 0)              while(sem_wait(&((*s_queue_signaux).semaphore)) != 0)
 #       else  #       else
             while(sem_wait(semaphore_queue_signaux) != 0)              while(sem_wait(semaphore_queue_signaux) != 0)
Line 2554  envoi_signal_processus(pid_t pid, enum s Line 2648  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;
   
 #       ifndef SEMAPHORES_NOMMES  #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
             if (sem_post(&((*s_queue_signaux).semaphore)) != 0)              if (sem_post(&((*s_queue_signaux).semaphore)) != 0)
 #       else  #       else
             if (sem_post(semaphore_queue_signaux) != 0)              if (sem_post(semaphore_queue_signaux) != 0)
Line 2562  envoi_signal_processus(pid_t pid, enum s Line 2656  envoi_signal_processus(pid_t pid, enum s
         {          {
             return(1);              return(1);
         }          }
   
   #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
               if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
   #       else
               if (sem_post(semaphore_signalisation) != 0)
   #       endif
           {
               return(1);
           }
     }      }
     else      else
     {      {
Line 2648  envoi_signal_processus(pid_t pid, enum s Line 2751  envoi_signal_processus(pid_t pid, enum s
                     return(1);                      return(1);
                 }                  }
   
                   if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))
                           == SEM_FAILED)
                   {
                       return(1);
                   }
   
                 while(sem_wait(semaphore) != 0)                  while(sem_wait(semaphore) != 0)
                 {                  {
                     if (errno != EINTR)                      if (errno != EINTR)
                     {                      {
                         sem_close(semaphore);                          sem_close(semaphore);
                           sem_close(signalisation);
                         return(1);                          return(1);
                     }                      }
                 }                  }
Line 2679  envoi_signal_processus(pid_t pid, enum s Line 2789  envoi_signal_processus(pid_t pid, enum s
                 {                  {
                     return(1);                      return(1);
                 }                  }
   
                   if (sem_post(&((*queue).signalisation)) != 0)
                   {
                       return(1);
                   }
 #           else  #           else
                 if (sem_post(semaphore) != 0)                  if (sem_post(semaphore) != 0)
                 {                  {
                     sem_close(semaphore);                      sem_close(semaphore);
                       sem_close(signalisation);
                     return(1);                      return(1);
                 }                  }
   
Line 2690  envoi_signal_processus(pid_t pid, enum s Line 2806  envoi_signal_processus(pid_t pid, enum s
                 {                  {
                     return(1);                      return(1);
                 }                  }
   
                   if (sem_post(signalisation) != 0)
                   {
                       sem_close(signalisation);
                       return(1);
                   }
   
                   if (sem_close(signalisation) != 0)
                   {
                       return(1);
                   }
   
 #           endif  #           endif
   
             if (munmap(queue, sizeof(struct_queue_signaux)) != 0)              if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
Line 2703  envoi_signal_processus(pid_t pid, enum s Line 2831  envoi_signal_processus(pid_t pid, enum s
                 return(1);                  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 2714  envoi_signal_processus(pid_t pid, enum s Line 2847  envoi_signal_processus(pid_t pid, enum s
 #       endif  #       endif
     }      }
   
     kill(pid, SIGALRM);  
   
     return(0);      return(0);
 }  }
   
Line 2753  envoi_signal_thread(pthread_t tid, enum Line 2884  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 2779  envoi_signal_thread(pthread_t tid, enum Line 2910  envoi_signal_thread(pthread_t tid, enum
         return(1);          return(1);
     }      }
   
     pthread_kill(tid, SIGALRM);  #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
       {
           return(1);
       }
   #   else
       if (sem_post(semaphore_signalisation) != 0)
       {
           return(1);
       }
   #   endif
   
     return(0);      return(0);
 }  }
Line 2788  int Line 2929  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));
   
     pthread_kill((*s_etat_processus_a_signaler).tid, SIGALRM);  #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
       {
           return(1);
       }
   #   else
       if (sem_post(semaphore_signalisation) != 0)
       {
           return(1);
       }
   #   endif
   
     return(0);      return(0);
 }  }
Line 2870  creation_queue_signaux(struct_processus Line 3021  creation_queue_signaux(struct_processus
 #       ifndef SEMAPHORES_NOMMES  #       ifndef SEMAPHORES_NOMMES
             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);
 #       else  #       else
             if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))              if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
                     == SEM_FAILED)                      == SEM_FAILED)
Line 2878  creation_queue_signaux(struct_processus Line 3030  creation_queue_signaux(struct_processus
                 return;                  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;
             }              }
   
               if ((semaphore_arret_signalisation = sem_init2(1, getpid(),
                       SEM_ARRET_SIGNALISATION)) == SEM_FAILED)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
 #       endif  #       endif
   
         (*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), 0))
Line 2953  creation_queue_signaux(struct_processus Line 3113  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 2976  creation_queue_signaux(struct_processus Line 3138  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 3054  creation_queue_signaux(struct_processus Line 3218  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.  #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       sem_wait(&((*s_queue_signaux).arret_signalisation));
   #   else
       sem_wait(semaphore_arret_signalisation);
   #   endif
   
     (*s_queue_signaux).requete_arret = d_vrai;      (*s_queue_signaux).requete_arret = d_vrai;
   
 #   ifndef SEMAPHORES_NOMMES  #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       sem_post(&((*s_queue_signaux).arret_signalisation));
   #   else
       sem_post(semaphore_arret_signalisation);
   #   endif
   
       // Incrémenter le sémaphore pour être sûr de le débloquer.
   
   #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
     sem_post(&((*s_queue_signaux).signalisation));      sem_post(&((*s_queue_signaux).signalisation));
 #   else  #   else
     sem_post(semaphore_signalisation);      sem_post(semaphore_signalisation);
Line 3077  liberation_queue_signaux(struct_processu Line 3253  liberation_queue_signaux(struct_processu
 #       endif  #       endif
 #   else // POSIX  #   else // POSIX
 #       ifndef SEMAPHORES_NOMMES  #       ifndef SEMAPHORES_NOMMES
             sem_close(&((*s_queue_signaux).semaphore));              // Rien à faire, les sémaphores sont anonymes.
             sem_close(&((*s_queue_signaux).signalisation));  
 #       else  #       else
             sem_close(semaphore_queue_signaux);              sem_close(semaphore_queue_signaux);
             sem_close(semaphore_signalisation);              sem_close(semaphore_signalisation);
               sem_close(semaphore_arret_signalisation);
 #       endif  #       endif
   
         if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)          if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
Line 3117  destruction_queue_signaux(struct_process Line 3293  destruction_queue_signaux(struct_process
         unsigned char       *nom;          unsigned char       *nom;
 #   endif  #   endif
   
   #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       sem_wait(&((*s_queue_signaux).arret_signalisation));
   #   else
       sem_wait(semaphore_arret_signalisation);
   #   endif
   
       (*s_queue_signaux).requete_arret = d_vrai;
   
   #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       sem_post(&((*s_queue_signaux).arret_signalisation));
   #   else
       sem_post(semaphore_arret_signalisation);
   #   endif
   
       // Incrémenter le sémaphore pour être sûr de le débloquer.
   
   #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       sem_post(&((*s_queue_signaux).signalisation));
   #   else
       sem_post(semaphore_signalisation);
   #   endif
   
       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.
Line 3139  destruction_queue_signaux(struct_process Line 3339  destruction_queue_signaux(struct_process
             unlink((*s_queue_signaux).signalisation.path);              unlink((*s_queue_signaux).signalisation.path);
             free((*s_queue_signaux).signalisation.path);              free((*s_queue_signaux).signalisation.path);
   
               if (semctl((*s_queue_signaux).arret_signalisation.sem, 0, IPC_RMID)
                       == -1)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               unlink((*s_queue_signaux).arret_signalisation.path);
               free((*s_queue_signaux).arret_signalisation.path);
   
             if (shmdt(s_queue_signaux) == -1)              if (shmdt(s_queue_signaux) == -1)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;                  (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
Line 3167  destruction_queue_signaux(struct_process Line 3377  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 3175  destruction_queue_signaux(struct_process Line 3388  destruction_queue_signaux(struct_process
 #       endif  #       endif
 #   else // POSIX  #   else // POSIX
 #       ifndef SEMAPHORES_NOMMES  #       ifndef SEMAPHORES_NOMMES
             sem_close(&((*s_queue_signaux).semaphore));  
             sem_destroy(&((*s_queue_signaux).semaphore));              sem_destroy(&((*s_queue_signaux).semaphore));
   
             sem_close(&((*s_queue_signaux).signalisation));  
             sem_destroy(&((*s_queue_signaux).signalisation));              sem_destroy(&((*s_queue_signaux).signalisation));
               sem_destroy(&((*s_queue_signaux).arret_signalisation));
 #       else  #       else
             sem_close(semaphore_queue_signaux);              sem_close(semaphore_queue_signaux);
             sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);              sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);
   
             sem_close(semaphore_signalisation);              sem_close(semaphore_signalisation);
             sem_destroy2(semaphore_signalisation, getpid(), SEM_SIGNALISATION);              sem_destroy2(semaphore_signalisation, getpid(), SEM_SIGNALISATION);
   
               sem_close(semaphore_arret_signalisation);
               sem_destroy2(semaphore_arret_signalisation, getpid(),
                       SEM_ARRET_SIGNALISATION);
 #       endif  #       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.96  
changed lines
  Added in v.1.137


CVSweb interface <joel.bertrand@systella.fr>