Diff for /rpl/src/interruptions.c between versions 1.105 and 1.186

version 1.105, 2012/10/09 15:27:45 version 1.186, 2016/09/27 15:29:39
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.11    RPL/2 (R) version 4.1.26
   Copyright (C) 1989-2012 Dr. BERTRAND Joël    Copyright (C) 1989-2016 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)
 {  {
     // Cette fonction est lancée dans un thread créé par processus pour      // Cette fonction est lancée dans un thread créé par processus pour
     // gérer le cas des appels système qui seraient bloqués lors de l'arrivée du      // gérer le cas des appels système qui seraient bloqués lors de l'arrivée du
     // signal SIGALRM. Les processus externes n'envoient plus un signal au      // signal SIGUSR2. Les processus externes n'envoient plus un signal au
     // processus ou au thread à signaler mais positionnent les informations      // processus ou au thread à signaler mais positionnent les informations
     // nécessaires dans la queue des signaux et incrémentent le sémaphore.      // nécessaires dans la queue des signaux et incrémentent le sémaphore.
     // Le sémaphore est décrémenté lorsque le signal est effectivement traité.      // Le sémaphore est décrémenté lorsque le signal est effectivement traité.
   
       int                                     ios;
     int                                     nombre_signaux_envoyes;      int                                     nombre_signaux_envoyes;
   
     struct_processus                        *s_etat_processus;      struct_processus                        *s_etat_processus;
Line 81  thread_surveillance_signaux(void *argume Line 79  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 91  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  
         {          {
               while((ios = sem_wait(semaphore_arret_signalisation)) != 0)
               {
                   if (errno != EINTR)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                   }
               }
   
             if ((*s_queue_signaux).requete_arret == d_vrai)              if ((*s_queue_signaux).requete_arret == d_vrai)
             {              {
                   sem_post(semaphore_arret_signalisation);
                   sem_post(semaphore_signalisation);
   
                 break;                  break;
             }              }
   
 #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)  
             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();  
   
             // 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.
   
 #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)              while((ios = sem_wait(semaphore_queue_signaux)) != 0)
             sem_wait(&(*s_queue_signaux).semaphore);              {
 #           else                  if (errno != EINTR)
             sem_wait(semaphore_queue_signaux);                  {
 #           endif                      (*s_etat_processus).erreur_systeme = d_es_processus;
                   }
               }
   
             if ((*s_queue_signaux).pointeur_lecture !=              if ((*s_queue_signaux).pointeur_lecture !=
                     (*s_queue_signaux).pointeur_ecriture)                      (*s_queue_signaux).pointeur_ecriture)
             {              {
                   // 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(), SIGUSR2);
                   sched_yield();
             }              }
   
 #           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              sem_post(semaphore_arret_signalisation);
   
             // Dans un second temps, on balaye toutes les queues de signaux              // Dans un second temps, on balaye toutes les queues de signaux
             // des threads du processus courant.              // des threads du processus courant.
   
               // 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 157  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, SIGUSR2);
                           sched_yield();
                     }                      }
   
                       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 191  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 352  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 558  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 607  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 675  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 776  liberation_threads(struct_processus *s_e
                 }                  }
             }              }
   
             liberation_arbre_variables(s_etat_processus,  
                     (*s_etat_processus).s_arbre_variables, d_faux);  
   
             // Ne peut être effacé qu'une seule fois              // Ne peut être effacé qu'une seule fois
             if (suppression_variables_partagees == d_faux)              if (suppression_variables_partagees == d_faux)
             {              {
                 suppression_variables_partagees = d_vrai;                  suppression_variables_partagees = d_vrai;
   
                 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));
                 {                  (*(*s_etat_processus).s_arbre_variables_partagees) = NULL;
                     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)                  (*(*s_etat_processus).l_liste_variables_partagees) = NULL;
                         .s_liste_variables_partagees).mutex));              }
                 pthread_mutex_unlock(&((*(*s_etat_processus)  
                         .s_liste_variables_partagees).mutex));              liberation_arbre_variables(s_etat_processus,
                       (*s_etat_processus).s_arbre_variables, d_faux);
   
               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 1245  liberation_threads(struct_processus *s_e Line 1278  liberation_threads(struct_processus *s_e
 #           endif  #           endif
   
             liberation_contexte_cas(s_etat_processus);              liberation_contexte_cas(s_etat_processus);
             free(s_etat_processus);              liberation_allocateur_buffer(s_etat_processus);
               sys_free(s_etat_processus);
   
             s_etat_processus = candidat;              s_etat_processus = candidat;
         }          }
Line 1287  liberation_threads(struct_processus *s_e Line 1321  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 1347  recherche_thread(pid_t pid, pthread_t ti Line 1380  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 1367  recherche_thread(pid_t pid, pthread_t ti Line 1405  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 1428  recherche_thread_principal(pid_t pid) Line 1472  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 1440  verrouillage_gestionnaire_signaux(struct Line 1482  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;  
     }  
   
   static inline void
   deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
   {
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
     if (sem_post(&semaphore_gestionnaires_signaux) == -1)      while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
 #   else  #   else
     if (sem_post(semaphore_gestionnaires_signaux) == -1)      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              BUG(1, uprintf("Unlock error !\n"));
         sem_wait((*s_etat_processus).semaphore_fork);              return;
 #       endif          }
         BUG(1, uprintf("Lock error !\n"));  
         return;  
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      return;
     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)  }
 #   else  
     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)  /*
 #   endif  ================================================================================
     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)
   {
       pthread_attr_t                  attributs;
   
       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("Lock error !\n"));  
         return;  
     }      }
   
     if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)      pipe_signaux = (*s_etat_processus).pipe_signaux[1];
   
       if (pthread_attr_init(&attributs) != 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;  
     }      }
   
     if (semaphore == 1)      if (pthread_attr_setdetachstate(&attributs, PTHREAD_CREATE_JOINABLE) != 0)
     {      {
         // Le semaphore ne peut être pris par le thread qui a appelé          (*s_etat_processus).erreur_systeme = d_es_processus;
         // le gestionnaire de signal car le signal est bloqué par ce thread          return(d_erreur);
         // 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)      if (pthread_create(&((*s_etat_processus).thread_signaux), &attributs,
         {              thread_signaux, s_etat_processus) != 0)
 #           ifndef SEMAPHORES_NOMMES      {
             sem_wait(&((*s_etat_processus).semaphore_fork));          (*s_etat_processus).erreur_systeme = d_es_processus;
 #           else          return(d_erreur);
             sem_wait((*s_etat_processus).semaphore_fork);  
 #           endif  
             BUG(1, uprintf("Lock error !\n"));  
             return;  
         }  
     }      }
   
     return;      if (pthread_attr_destroy(&attributs) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return(d_erreur);
       }
   
       return(d_absence_erreur);
 }  }
   
 static inline void  logical1
 deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)  arret_thread_signaux(struct_processus *s_etat_processus)
 {  {
     int         semaphore;      unsigned char       signal;
       ssize_t             n;
   
     // Il faut respecteur l'atomicité des deux opérations suivantes !      signal = (unsigned char ) (rpl_sigmax & 0xFF);
   
     if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) == -1)      do
     {      {
 #       ifndef SEMAPHORES_NOMMES          n = write_atomic(s_etat_processus, (*s_etat_processus).pipe_signaux[1],
         sem_wait(&((*s_etat_processus).semaphore_fork));                  &signal, sizeof(signal));
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }  
   
 #   ifndef SEMAPHORES_NOMMES          if (n < 0)
     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)          {
 #   else              return(d_erreur);
     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)          }
 #   endif      } while(n != 1);
     {  
 #       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      pthread_join((*s_etat_processus).thread_signaux, NULL);
     while(sem_wait(&semaphore_gestionnaires_signaux) == -1)  
 #   else      close((*s_etat_processus).pipe_signaux[1]);
     while(sem_wait(semaphore_gestionnaires_signaux) == -1)      return(d_absence_erreur);
 #   endif  }
   
   void *
   thread_signaux(void *argument)
   {
       int                     *pipe;
   
       sigset_t                masque;
   
       struct pollfd           fds;
   
       struct_processus        *s_etat_processus;
   
       unsigned char           signal;
   
       s_etat_processus = (struct_processus *) argument;
       pipe = (*s_etat_processus).pipe_signaux;
       fds.fd = pipe[0];
       fds.events = POLLIN;
   
       sigfillset(&masque);
       pthread_sigmask(SIG_BLOCK, &masque, NULL);
   
       do
     {      {
         if (errno != EINTR)          fds.revents = 0;
   
           while(poll(&fds, 1, -1) == -1)
         {          {
 #           ifndef SEMAPHORES_NOMMES              if (errno != EINTR)
             sem_wait(&((*s_etat_processus).semaphore_fork));              {
 #           else                  close((*s_etat_processus).pipe_signaux[0]);
             sem_wait((*s_etat_processus).semaphore_fork);                  pthread_exit(NULL);
 #           endif              }
             BUG(1, uprintf("Unlock error !\n"));  
             return;  
         }          }
     }  
   
     if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)          if (read_atomic(s_etat_processus, fds.fd, &signal, 1) != 1)
     {          {
 #       ifndef SEMAPHORES_NOMMES              close((*s_etat_processus).pipe_signaux[0]);
         sem_wait(&((*s_etat_processus).semaphore_fork));              pthread_exit(NULL);
 #       else          }
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }  
   
 #   ifndef SEMAPHORES_NOMMES          if (signal != (0xFF & rpl_sigmax))
     while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)  
 #   else  
     while(sem_wait((*s_etat_processus).semaphore_fork) != 0)  
 #   endif  
     {  
         if (errno != EINTR)  
         {          {
             BUG(1, uprintf("Unlock error !\n"));              envoi_signal_processus(getpid(), signal, d_faux);
             return;              // Un signal SIGUSR2 est envoyé par le thread de surveillance
               // des signaux jusqu'à ce que les signaux soient tous traités.
         }          }
     }      } while(signal != (0xFF & rpl_sigmax));
   
       close((*s_etat_processus).pipe_signaux[0]);
       pthread_exit(NULL);
   }
   
     if (semaphore == 1)  
   static inline void
   _write(int fd, const void *buf, size_t count)
   {
       ssize_t         ios;
   
       while((ios = write(fd, buf, count)) == -1)
     {      {
         if (pthread_mutex_unlock(&mutex_liste_threads) != 0)          if (errno != EINTR)
         {          {
             BUG(1, uprintf("Unlock error !\n"));              break;
             return;  
         }          }
     }      }
   
     return;      return;
 }  }
   
 #define test_signal(signal) \  
     if (signal_test == SIGTEST) { signal_test = signal; return; }  
   
 // Récupération des signaux  // Récupération des signaux
 // - SIGINT  (arrêt au clavier)  // - SIGINT  (arrêt au clavier)
Line 1614  deverrouillage_gestionnaire_signaux(stru Line 1663  deverrouillage_gestionnaire_signaux(stru
 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;              break;
   
         default:          default:
             // SIGALRM              // SIGUSR2
             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);
       }
   
   #   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);
       _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);
   
   #   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;
   }
   
 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 1662  signal_alrm(struct_processus *s_etat_pro Line 1819  signal_alrm(struct_processus *s_etat_pro
         {          {
             // On n'est pas dans le processus père, on remonte le signal.              // On n'est pas dans le processus père, on remonte le signal.
             envoi_signal_processus((*s_etat_processus).pid_processus_pere,              envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                     rpl_sigalrm);                      rpl_sigalrm, d_faux);
         }          }
         else          else
         {          {
Line 1707  signal_term(struct_processus *s_etat_pro Line 1864  signal_term(struct_processus *s_etat_pro
         if ((*s_etat_processus).pid_processus_pere != getpid())          if ((*s_etat_processus).pid_processus_pere != getpid())
         {          {
             envoi_signal_processus((*s_etat_processus).pid_processus_pere,              envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                     rpl_sigterm);                      rpl_sigterm, d_faux);
         }          }
         else          else
         {          {
Line 1761  signal_int(struct_processus *s_etat_proc Line 1918  signal_int(struct_processus *s_etat_proc
         if ((*s_etat_processus).pid_processus_pere != getpid())          if ((*s_etat_processus).pid_processus_pere != getpid())
         {          {
             envoi_signal_processus((*s_etat_processus).pid_processus_pere,              envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                     rpl_sigint);                      rpl_sigint, d_faux);
         }          }
         else          else
         {          {
Line 1807  signal_int(struct_processus *s_etat_proc Line 1964  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 1850  signal_tstp(struct_processus *s_etat_pro Line 1989  signal_tstp(struct_processus *s_etat_pro
         if ((*s_etat_processus).var_volatile_processus_pere == 0)          if ((*s_etat_processus).var_volatile_processus_pere == 0)
         {          {
             envoi_signal_processus((*s_etat_processus).pid_processus_pere,              envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                     rpl_sigtstp);                      rpl_sigtstp, d_faux);
         }          }
         else          else
         {          {
Line 1872  signal_tstp(struct_processus *s_etat_pro Line 2011  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 1921  sortie_interruption_depassement_pile(voi Line 2028  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 1939  interruption_depassement_pile(int urgenc Line 2045  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 1968  interruption_violation_access(void *adre Line 2073  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 2115  signal_inject(struct_processus *s_etat_p Line 2225  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 2228  signal_abort(struct_processus *s_etat_pr Line 2319  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 2254  signal_hup(struct_processus *s_etat_proc Line 2335  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 2267  signal_hup(struct_processus *s_etat_proc Line 2352  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 2283  traitement_exceptions_gsl(const char *re Line 2370  traitement_exceptions_gsl(const char *re
         int line, int gsl_errno)          int line, int gsl_errno)
 {  {
     code_erreur_gsl = gsl_errno;      code_erreur_gsl = gsl_errno;
     envoi_signal_processus(getpid(), rpl_sigexcept);      envoi_signal_processus(getpid(), rpl_sigexcept, d_faux);
     return;      return;
 }  }
   
Line 2364  envoi_interruptions(struct_processus *s_ Line 2451  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 2387  scrutation_interruptions(struct_processu Line 2474  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 2407  scrutation_interruptions(struct_processu Line 2490  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);              {
                   sem_post(semaphore_queue_signaux);
                   (*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(&mutex_liste_threads) == 0)
     {      {
         while((*s_etat_processus).pointeur_signal_lecture !=          if (pthread_mutex_trylock(&((*s_etat_processus).mutex_signaux)) == 0)
                 (*s_etat_processus).pointeur_signal_ecriture)  
         {          {
             // Il y a un signal dans la queue du thread courant. On le traite.              while((*s_etat_processus).pointeur_signal_lecture !=
                       (*s_etat_processus).pointeur_signal_ecriture)
               {
                   // Il y a un signal dans la queue du thread courant.
                   // On le traite.
   
             envoi_interruptions(s_etat_processus,                  envoi_interruptions(s_etat_processus,
                     (*s_etat_processus).signaux_en_queue                          (*s_etat_processus).signaux_en_queue
                     [(*s_etat_processus).pointeur_signal_lecture],                          [(*s_etat_processus).pointeur_signal_lecture],
                     getpid());                          getpid());
             (*s_etat_processus).pointeur_signal_lecture =                  (*s_etat_processus).pointeur_signal_lecture =
                     ((*s_etat_processus).pointeur_signal_lecture + 1)                          ((*s_etat_processus).pointeur_signal_lecture + 1)
                     % LONGUEUR_QUEUE_SIGNAUX;                          % LONGUEUR_QUEUE_SIGNAUX;
   
 #           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                          if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
                           {
                               (*s_etat_processus).erreur_systeme = d_es_processus;
                               return;
                           }
   
                           (*s_etat_processus).erreur_systeme = d_es_processus;
                           return;
                       }
                   }
               }
   
               pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux));
         }          }
   
         pthread_mutex_unlock(&mutex_interruptions);          pthread_mutex_unlock(&mutex_liste_threads);
     }      }
   
     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 2472  nom_segment(unsigned char *chemin, pid_t Line 2580  nom_segment(unsigned char *chemin, pid_t
 #   ifdef IPCS_SYSV // !POSIX  #   ifdef IPCS_SYSV // !POSIX
 #       ifndef OS2 // !OS2  #       ifndef OS2 // !OS2
   
             if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *              if ((fichier = sys_malloc((strlen(chemin) + 1 + 256 + 1) *
                     sizeof(unsigned char))) == NULL)                      sizeof(unsigned char))) == NULL)
             {              {
                 return(NULL);                  return(NULL);
Line 2480  nom_segment(unsigned char *chemin, pid_t Line 2588  nom_segment(unsigned char *chemin, pid_t
   
             sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);              sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
 #       else // OS2  #       else // OS2
             if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char)))              if ((fichier = sys_malloc((10 + 256 + 1) * sizeof(unsigned char)))
                     == NULL)                      == NULL)
             {              {
                 return(NULL);                  return(NULL);
Line 2490  nom_segment(unsigned char *chemin, pid_t Line 2598  nom_segment(unsigned char *chemin, pid_t
 #       endif // OS2  #       endif // OS2
 #   else // POSIX  #   else // POSIX
   
         if ((fichier = malloc((1 + 256 + 1) *          if ((fichier = sys_malloc((1 + 256 + 1) *
                 sizeof(unsigned char))) == NULL)                  sizeof(unsigned char))) == NULL)
         {          {
             return(NULL);              return(NULL);
Line 2516  nom_segment(unsigned char *chemin, pid_t Line 2624  nom_segment(unsigned char *chemin, pid_t
 */  */
   
 int  int
 envoi_signal_processus(pid_t pid, enum signaux_rpl signal)  envoi_signal_processus(pid_t pid, enum signaux_rpl signal,
           logical1 test_ouverture)
 {  {
 #   ifndef OS2  #   ifndef OS2
         int                         segment;          int                         segment;
 #   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 2536  envoi_signal_processus(pid_t pid, enum s Line 2645  envoi_signal_processus(pid_t pid, enum s
   
     struct_queue_signaux            *queue;      struct_queue_signaux            *queue;
   
       struct timespec                 attente;
   
     unsigned char                   *nom;      unsigned char                   *nom;
   
     // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en      // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en
Line 2550  envoi_signal_processus(pid_t pid, enum s Line 2661  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 2571  envoi_signal_processus(pid_t pid, enum s Line 2678  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)          {
               sem_post(semaphore_queue_signaux);
               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 2600  envoi_signal_processus(pid_t pid, enum s Line 2708  envoi_signal_processus(pid_t pid, enum s
             }              }
   
 #           ifndef OS2 // SysV  #           ifndef OS2 // SysV
                 if ((desc = open(nom, O_RDWR)) == -1)                  if (test_ouverture == d_vrai)
                 {                  {
                     free(nom);                      attente.tv_sec = 0;
                     return(1);                      attente.tv_nsec = GRANULARITE_us * 1000;
   
                       while((desc = open(nom, O_RDWR)) == -1)
                       {
                           nanosleep(&attente, NULL);
                           INCR_GRANULARITE(attente.tv_nsec);
                       }
                   }
                   else
                   {
                       if ((desc = open(nom, O_RDWR)) == -1)
                       {
                           sys_free(nom);
                           return(1);
                       }
                 }                  }
   
                 close(desc);                  close(desc);
   
                 if ((clef = ftok(nom, 1)) == -1)                  if ((clef = ftok(nom, 1)) == -1)
                 {                  {
                     free(nom);                      sys_free(nom);
                     return(1);                      return(1);
                 }                  }
   
                 free(nom);                  sys_free(nom);
   
                 if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0))                  if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0))
                         == -1)                          == -1)
Line 2624  envoi_signal_processus(pid_t pid, enum s Line 2746  envoi_signal_processus(pid_t pid, enum s
   
                 queue = shmat(segment, NULL, 0);                  queue = shmat(segment, NULL, 0);
 #           else // OS/2  #           else // OS/2
                 if (DosGetNamedSharedMem((PVOID) &queue, nom,                  if (test_ouverture == d_vrai)
                         PAG_WRITE | PAG_READ) != 0)  
                 {                  {
                     free(nom);                      attente.tv_sec = 0;
                     return(1);                      attente.tv_nsec = GRANULARITE_us * 1000;
   
                       while(DosGetNamedSharedMem((PVOID) &queue, nom,
                               PAG_WRITE | PAG_READ) != 0)
                       {
                           nanosleep(&attente, NULL);
                           INCR_GRANULARITE(attente.tv_nsec);
                       }
                   }
                   else
                   {
                       if (DosGetNamedSharedMem((PVOID) &queue, nom,
                               PAG_WRITE | PAG_READ) != 0)
                       {
                           sys_free(nom);
                           return(1);
                       }
                 }                  }
   
                 free(nom);                  sys_free(nom);
 #           endif  #           endif
 #       else // POSIX  #       else // POSIX
             if ((nom = nom_segment(racine_segment, pid)) == NULL)              if ((nom = nom_segment(racine_segment, pid)) == NULL)
Line 2639  envoi_signal_processus(pid_t pid, enum s Line 2776  envoi_signal_processus(pid_t pid, enum s
                 return(1);                  return(1);
             }              }
   
             if ((segment = shm_open(nom, O_RDWR, 0)) == -1)              if (test_ouverture == d_vrai)
             {              {
                 free(nom);                  attente.tv_sec = 0;
                 return(1);                  attente.tv_nsec = GRANULARITE_us * 1000;
   
                   while((segment = shm_open(nom, O_RDWR, 0)) == -1)
                   {
                       nanosleep(&attente, NULL);
                       INCR_GRANULARITE(attente.tv_nsec);
                   }
               }
               else
               {
                   if ((segment = shm_open(nom, O_RDWR, 0)) == -1)
                   {
                       sys_free(nom);
                       return(1);
                   }
             }              }
   
             free(nom);              sys_free(nom);
   
             if ((queue = mmap(NULL, sizeof(struct_queue_signaux),              if ((queue = mmap(NULL, sizeof(struct_queue_signaux),
                     PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0)) ==                      PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0)) ==
Line 2656  envoi_signal_processus(pid_t pid, enum s Line 2807  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)  #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                 {                  {
                     if (errno != EINTR)                      munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       return(1);
                   }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                     {                      {
                         return(1);                          return(1);
                     }                      }
                 }  #               else // OS/2
 #           else                      // Pendant de DosGetNamedSHaredMem()
                 if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)  #               endif
   #           endif
               return(1);
           }
   
           if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))
                   == SEM_FAILED)
           {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                 {                  {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       sem_close(semaphore);
                     return(1);                      return(1);
                 }                  }
   
                 if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))                  if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                         == SEM_FAILED)  
                 {                  {
                       close(segment);
                       sem_close(semaphore);
                     return(1);                      return(1);
                 }                  }
   
                 while(sem_wait(semaphore) != 0)                  close(segment);
                 {  #           else // IPCS_SYSV
                     if (errno != EINTR)  #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                     {                      {
                         sem_close(semaphore);                          sem_close(semaphore);
                         sem_close(signalisation);  
                         return(1);                          return(1);
                     }                      }
                 }  #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
 #           endif  #           endif
 #       else // IPCS_SYSV  
             while(sem_wait(&((*queue).semaphore)) != 0)              sem_close(semaphore);
               return(1);
           }
   
           while(sem_wait(semaphore) != 0)
           {
               if (errno != EINTR)
             {              {
                 if (errno != EINTR)  #               ifndef IPCS_SYSV // POSIX
                 {                      if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE)
                     return(1);                              != 0)
                 }                      {
                           munmap(queue, sizeof(struct_queue_signaux));
                           sem_close(semaphore);
                           sem_close(signalisation);
                           close(segment);
                           return(1);
                       }
   
                       if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                       {
                           sem_close(semaphore);
                           sem_close(signalisation);
                           close(segment);
                           return(1);
                       }
   
                       close(segment);
   #               else // IPCS_SYSV
   #                   ifndef OS2 // SysV
                           if (shmdt(queue) != 0)
                           {
                               sem_close(semaphore);
                               sem_close(signalisation);
                               return(1);
                           }
   #                   else // OS/2
                           // Pendant de DosGetNamedSHaredMem()
   #                   endif
   #               endif
   
                   sem_close(semaphore);
                   sem_close(signalisation);
                   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 2706  envoi_signal_processus(pid_t pid, enum s Line 2925  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          if (sem_post(semaphore) != 0)
 #           ifndef SEMAPHORES_NOMMES          {
                 if (sem_post(&((*queue).semaphore)) != 0)  #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                 {                  {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       sem_close(semaphore);
                       sem_close(signalisation);
                     return(1);                      return(1);
                 }                  }
   
                 if (sem_post(&((*queue).signalisation)) != 0)                  if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                 {                  {
                       close(segment);
                       sem_close(semaphore);
                       sem_close(signalisation);
                     return(1);                      return(1);
                 }                  }
 #           else  
                 if (sem_post(semaphore) != 0)                  close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           sem_close(semaphore);
                           sem_close(signalisation);
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
   
               sem_close(semaphore);
               sem_close(signalisation);
               return(1);
           }
   
           if (sem_close(semaphore) != 0)
           {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                 {                  {
                     sem_close(semaphore);                      munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                     sem_close(signalisation);                      sem_close(signalisation);
                     return(1);                      return(1);
                 }                  }
   
                 if (sem_close(semaphore) != 0)                  if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                 {                  {
                       close(segment);
                       sem_close(signalisation);
                     return(1);                      return(1);
                 }                  }
   
                 if (sem_post(signalisation) != 0)                  close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           sem_close(signalisation);
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
   
               sem_close(signalisation);
               return(1);
           }
   
           if (sem_post(signalisation) != 0)
           {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                 {                  {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                     sem_close(signalisation);                      sem_close(signalisation);
                     return(1);                      return(1);
                 }                  }
   
                 if (sem_close(signalisation) != 0)                  if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                 {                  {
                       close(segment);
                       sem_close(signalisation);
                     return(1);                      return(1);
                 }                  }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           sem_close(signalisation);
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
 #           endif  #           endif
   
             if (munmap(queue, sizeof(struct_queue_signaux)) != 0)              sem_close(signalisation);
             {              return(1);
           }
   
           if (sem_close(signalisation) != 0)
           {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                   {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       return(1);
                   }
   
                 close(segment);                  close(segment);
                 return(1);  #           else // IPCS_SYSV
             }  #               ifndef OS2 // SysV
 #       else // IPCS_SYSV                      if (shmdt(queue) != 0)
             if (sem_post(&((*queue).semaphore)) != 0)                      {
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
   
               return(1);
           }
   
   #       ifndef IPCS_SYSV // POSIX
               if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
             {              {
                   munmap(queue, sizeof(struct_queue_signaux));
                   close(segment);
                 return(1);                  return(1);
             }              }
   
             if (sem_post(&((*queue).signalisation)) != 0)              if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
             {              {
                   close(segment);
                 return(1);                  return(1);
             }              }
   
               close(segment);
   #       else // IPCS_SYSV
 #           ifndef OS2 // SysV  #           ifndef OS2 // SysV
                 if (shmdt(queue) != 0)                  if (shmdt(queue) != 0)
                 {                  {
Line 2807  envoi_signal_thread(pthread_t tid, enum Line 3129  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 2833  envoi_signal_thread(pthread_t tid, enum Line 3155  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 2852  int Line 3167  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 2897  creation_queue_signaux(struct_processus Line 3205  creation_queue_signaux(struct_processus
   
     unsigned char                   *nom;      unsigned char                   *nom;
   
       if (lancement_thread_signaux(s_etat_processus) == d_erreur)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
     racine_segment = (*s_etat_processus).chemin_fichiers_temporaires;      racine_segment = (*s_etat_processus).chemin_fichiers_temporaires;
   
 #   ifndef IPCS_SYSV // POSIX  #   ifndef IPCS_SYSV // POSIX
Line 2910  creation_queue_signaux(struct_processus Line 3224  creation_queue_signaux(struct_processus
         if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,          if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
                 S_IRUSR | S_IWUSR)) == -1)                  S_IRUSR | S_IWUSR)) == -1)
         {          {
             free(nom);              if (errno != EEXIST)
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              {
             return;                  sys_free(nom);
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               if ((*s_etat_processus).langue == 'F')
               {
                   printf("+++Attention : Le segment de mémoire %s préexiste !\n",
                           nom);
               }
               else
               {
                   printf("+++Warning: %s memory segment preexists!\n", nom);
               }
   
               if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_TRUNC,
                       S_IRUSR | S_IWUSR)) == -1)
               {
                   sys_free(nom);
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
         }          }
   
         if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)          if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)
         {          {
             free(nom);              sys_free(nom);
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
             return;              return;
         }          }
Line 2929  creation_queue_signaux(struct_processus Line 3264  creation_queue_signaux(struct_processus
         {          {
             if (shm_unlink(nom) == -1)              if (shm_unlink(nom) == -1)
             {              {
                 free(nom);                  sys_free(nom);
                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;                  (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                 return;                  return;
             }              }
   
             free(nom);              sys_free(nom);
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
             return;              return;
         }          }
   
         free(nom);          sys_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_ASYNC | MS_INVALIDATE) != 0)
         {          {
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
             return;              return;
Line 3000  creation_queue_signaux(struct_processus Line 3339  creation_queue_signaux(struct_processus
             }              }
   
             close(support);              close(support);
             free(nom);              sys_free(nom);
   
             if ((segment = shmget(clef, sizeof(struct_queue_signaux),              if ((segment = shmget(clef, sizeof(struct_queue_signaux),
                     IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)                      IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
Line 3025  creation_queue_signaux(struct_processus Line 3364  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 3041  creation_queue_signaux(struct_processus Line 3399  creation_queue_signaux(struct_processus
                     sizeof(struct_queue_signaux),                      sizeof(struct_queue_signaux),
                     PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)                      PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
             {              {
                 free(nom);                  sys_free(nom);
                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;                  (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                 return;                  return;
             }              }
   
             free(nom);              sys_free(nom);
   
             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 3071  creation_queue_signaux(struct_processus Line 3431  creation_queue_signaux(struct_processus
         return;          return;
     }      }
   
 #   ifdef SCHED_OTHER      (*s_queue_signaux).controle = getpid();
     if (pthread_attr_setschedpolicy(&attributs, SCHED_OTHER) != 0)  
     {  
         (*s_etat_processus).erreur_systeme = d_es_processus;  
         return;  
     }  
 #   endif  
   
 #   ifdef PTHREAD_EXPLICIT_SCHED  
     if (pthread_attr_setinheritsched(&attributs, PTHREAD_EXPLICIT_SCHED) != 0)  
     {  
         (*s_etat_processus).erreur_systeme = d_es_processus;  
         return;  
     }  
 #   endif  
   
 #   ifdef PTHREAD_SCOPE_SYSTEM      if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs,
     if (pthread_attr_setscope(&attributs, PTHREAD_SCOPE_SYSTEM) != 0)              thread_surveillance_signaux, s_etat_processus) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
 #   endif  
   
     if (pthread_attr_destroy(&attributs) != 0)      if (pthread_attr_destroy(&attributs) != 0)
     {      {
Line 3101  creation_queue_signaux(struct_processus Line 3446  creation_queue_signaux(struct_processus
         return;          return;
     }      }
   
     if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs,  #   ifndef IPCS_SYSV
             thread_surveillance_signaux, s_etat_processus) != 0)      if (msync(s_queue_signaux, sizeof(s_queue_signaux),
               MS_ASYNC | MS_INVALIDATE) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
   #           endif
   
     return;      return;
 }  }
Line 3128  creation_queue_signaux(struct_processus Line 3475  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.  
   
     (*s_queue_signaux).requete_arret = d_vrai;  
   
 #   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
             if (shmdt(s_queue_signaux) == -1)              if (shmdt(s_queue_signaux) == -1)
Line 3150  liberation_queue_signaux(struct_processu Line 3485  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 3191  destruction_queue_signaux(struct_process Line 3522  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.      // On dépile les interruptions pour arrêter les SIGUSR2 sur
       // le processus courant.
   
       scrutation_interruptions(s_etat_processus);
   
       while(sem_wait(semaphore_arret_signalisation) != 0)
       {
           if (errno != EINTR)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
       }
   
     (*s_queue_signaux).requete_arret = d_vrai;      (*s_queue_signaux).requete_arret = d_vrai;
   
 #   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
   
     pthread_join((*s_queue_signaux).thread_signaux, NULL);      sem_post(semaphore_arret_signalisation);
   
       // Incrémenter le sémaphore pour être sûr de le débloquer.
   
       sem_post(semaphore_signalisation);
   
       if ((*s_queue_signaux).controle == getpid())
       {
           pthread_join((*s_queue_signaux).thread_signaux, NULL);
       }
       else
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
 #   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;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                 return;                  return;
             }              }
   
             unlink((*s_queue_signaux).semaphore.path);              unlink((*semaphore_queue_signaux).path);
             free((*s_queue_signaux).semaphore.path);              sys_free((*semaphore_queue_signaux).path);
   
             if (semctl((*s_queue_signaux).signalisation.sem, 0, IPC_RMID) == -1)              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).signalisation.path);              unlink((*semaphore_signalisation).path);
             free((*s_queue_signaux).signalisation.path);              sys_free((*semaphore_signalisation).path);
   
               if (semctl((*semaphore_arret_signalisation).sem, 0, IPC_RMID) == -1)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               unlink((*semaphore_arret_signalisation).path);
               sys_free((*semaphore_arret_signalisation).path);
   
             if (shmdt(s_queue_signaux) == -1)              if (shmdt(s_queue_signaux) == -1)
             {              {
Line 3245  destruction_queue_signaux(struct_process Line 3609  destruction_queue_signaux(struct_process
             }              }
   
             unlink(nom);              unlink(nom);
             free(nom);              sys_free(nom);
 #       else  #       else
             sem_close(&((*s_queue_signaux).semaphore));              sem_close(&((*s_queue_signaux).semaphore));
             sem_destroy(&((*s_queue_signaux).semaphore));              sem_destroy(&((*s_queue_signaux).semaphore));
Line 3253  destruction_queue_signaux(struct_process Line 3617  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 3260  destruction_queue_signaux(struct_process Line 3627  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)
         {          {
Line 3290  destruction_queue_signaux(struct_process Line 3648  destruction_queue_signaux(struct_process
   
         if (shm_unlink(nom) != 0)          if (shm_unlink(nom) != 0)
         {          {
             free(nom);              sys_free(nom);
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
             return;              return;
         }          }
   
         free(nom);          sys_free(nom);
 #   endif  #   endif
   
       arret_thread_signaux(s_etat_processus);
     return;      return;
 }  }
   

Removed from v.1.105  
changed lines
  Added in v.1.186


CVSweb interface <joel.bertrand@systella.fr>