Diff for /rpl/src/interruptions.c between versions 1.88 and 1.134

version 1.88, 2011/11/30 12:15:18 version 1.134, 2013/05/30 09:41:41
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.5    RPL/2 (R) version 4.1.14
   Copyright (C) 1989-2011 Dr. BERTRAND Joël    Copyright (C) 1989-2013 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
   
Line 52  typedef struct liste_chainee_volatile Line 52  typedef struct liste_chainee_volatile
     volatile void                           *donnee;      volatile void                           *donnee;
 } struct_liste_chainee_volatile;  } struct_liste_chainee_volatile;
   
   
 static volatile struct_liste_chainee_volatile   *liste_threads  static volatile struct_liste_chainee_volatile   *liste_threads
         = NULL;          = NULL;
 static volatile struct_liste_chainee_volatile   *liste_threads_surveillance  static volatile struct_liste_chainee_volatile   *liste_threads_surveillance
Line 61  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  static void *
         = PTHREAD_MUTEX_INITIALIZER;  thread_surveillance_signaux(void *argument)
   {
       // 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
       // signal SIGALRM. Les processus externes n'envoient plus un signal au
       // processus ou au thread à signaler mais positionnent les informations
       // 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é.
   
       int                                     nombre_signaux_envoyes;
   
       struct_processus                        *s_etat_processus;
   
       struct timespec                         attente;
   
       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;
   
       for(;;)
       {
           attente.tv_sec = 0;
           attente.tv_nsec = GRANULARITE_us * 1000;
   
   #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
           if (sem_wait(&(*s_queue_signaux).signalisation) == 0)
   #       else
           if (sem_wait(semaphore_signalisation) == 0)
   #       endif
           {
   #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
               if (sem_wait(&(*s_queue_signaux).arret_signalisation) != 0)
   #           else
               if (sem_wait(semaphore_arret_signalisation) != 0)
   #           endif
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
               }
   
               if ((*s_queue_signaux).requete_arret == d_vrai)
               {
   #               if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
                   sem_post(&(*s_queue_signaux).arret_signalisation);
                   sem_post(&(*s_queue_signaux).signalisation);
   #               else
                   sem_post(semaphore_arret_signalisation);
                   sem_post(semaphore_signalisation);
   #               endif
   
                   break;
               }
   
   #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
               sem_post(&(*s_queue_signaux).arret_signalisation);
               sem_post(&(*s_queue_signaux).signalisation);
   #           else
               sem_post(semaphore_arret_signalisation);
               sem_post(semaphore_signalisation);
   #           endif
   
               nombre_signaux_envoyes = 0;
               sched_yield();
   
               // Dans un premier temps, on verrouille la queue des signaux
               // affectée au processus courant pour vérifier s'il y a quelque
               // chose à traiter.
   
   #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
               sem_wait(&(*s_queue_signaux).semaphore);
   #           else
               sem_wait(semaphore_queue_signaux);
   #           endif
   
               if ((*s_queue_signaux).pointeur_lecture !=
                       (*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++;
                   kill(getpid(), SIGALRM);
               }
   
   #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
               sem_post(&(*s_queue_signaux).semaphore);
   #           else
               sem_post(semaphore_queue_signaux);
   #           endif
   
               // Dans un second temps, on balaye toutes les queues de signaux
               // 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);
   
               l_element_courant = liste_threads;
   
               while(l_element_courant != NULL)
               {
                   if ((*((struct_thread *) (*l_element_courant).donnee)).pid
                           == getpid())
                   {
                       pthread_mutex_lock(&((*(*((struct_thread *)
                               (*l_element_courant).donnee)).s_etat_processus)
                               .mutex_signaux));
   
                       if ((*(*((struct_thread *) (*l_element_courant).donnee))
                               .s_etat_processus).pointeur_signal_ecriture !=
                               (*(*((struct_thread *) (*l_element_courant)
                               .donnee)).s_etat_processus)
                               .pointeur_signal_lecture)
                       {
                           nombre_signaux_envoyes++;
                           pthread_kill((*((struct_thread *)
                                   (*l_element_courant).donnee)).tid, SIGALRM);
                       }
   
                       pthread_mutex_unlock(&((*(*((struct_thread *)
                               (*l_element_courant).donnee)).s_etat_processus)
                               .mutex_signaux));
                   }
   
                   l_element_courant = (*l_element_courant).suivant;
               }
   
               pthread_mutex_unlock(&mutex_liste_threads);
   
               // Nanosleep
   
               if (nombre_signaux_envoyes > 0)
               {
                   nanosleep(&attente, NULL);
               }
           }
           else
           {
               if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
               }
           }
       }
   
       pthread_exit(NULL);
   }
   
 void  void
 modification_pid_thread_pere(struct_processus *s_etat_processus)  modification_pid_thread_pere(struct_processus *s_etat_processus)
Line 207  retrait_thread(struct_processus *s_etat_ Line 360  retrait_thread(struct_processus *s_etat_
         return;          return;
     }      }
   
       // Le thread ne peut plus traiter de signaux explicites. Il convient
       // alors de corriger le sémaphore pour annuler les signaux en attente.
   
       while((*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus)
               .pointeur_signal_ecriture != (*(*((struct_thread *)
               (*l_element_courant).donnee)).s_etat_processus)
               .pointeur_signal_lecture)
       {
   #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
           while(sem_wait(&((*s_queue_signaux).signalisation)) != 0)
   #       else
           while(sem_wait(semaphore_signalisation) != 0)
   #       endif
           {
               if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
           }
   
           (*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus)
                   .pointeur_signal_lecture = ((*(*((struct_thread *)
                   (*l_element_courant).donnee)).s_etat_processus)
                   .pointeur_signal_lecture + 1) % LONGUEUR_QUEUE_SIGNAUX;
       }
   
     free((void *) (*l_element_courant).donnee);      free((void *) (*l_element_courant).donnee);
     free((struct_liste_chainee_volatile *) l_element_courant);      free((struct_liste_chainee_volatile *) l_element_courant);
   
Line 398  liberation_threads(struct_processus *s_e Line 578  liberation_threads(struct_processus *s_e
   
     struct_processus                            *candidat;      struct_processus                            *candidat;
   
     unsigned long                               i;      struct_liste_variables_partagees            *l_element_partage_courant;
       struct_liste_variables_partagees            *l_element_partage_suivant;
   
       struct_liste_variables_statiques            *l_element_statique_courant;
       struct_liste_variables_statiques            *l_element_statique_suivant;
   
       integer8                                    i;
   
     void                                        *element_candidat;      void                                        *element_candidat;
     void                                        *element_courant;      void                                        *element_courant;
Line 441  liberation_threads(struct_processus *s_e Line 627  liberation_threads(struct_processus *s_e
             close((*s_etat_processus).pipe_injections);              close((*s_etat_processus).pipe_injections);
             close((*s_etat_processus).pipe_nombre_injections);              close((*s_etat_processus).pipe_nombre_injections);
             close((*s_etat_processus).pipe_interruptions);              close((*s_etat_processus).pipe_interruptions);
             close((*s_etat_processus).pipe_nombre_objets_attente);              close((*s_etat_processus).pipe_nombre_elements_attente);
             close((*s_etat_processus).pipe_nombre_interruptions_attente);  
   
             liberation(s_etat_processus, (*s_etat_processus).at_exit);              liberation(s_etat_processus, (*s_etat_processus).at_exit);
   
Line 510  liberation_threads(struct_processus *s_e Line 695  liberation_threads(struct_processus *s_e
                     close((*s_argument_thread).pipe_acquittement[1]);                      close((*s_argument_thread).pipe_acquittement[1]);
                     close((*s_argument_thread).pipe_injections[1]);                      close((*s_argument_thread).pipe_injections[1]);
                     close((*s_argument_thread).pipe_nombre_injections[1]);                      close((*s_argument_thread).pipe_nombre_injections[1]);
                     close((*s_argument_thread).pipe_nombre_objets_attente[0]);                      close((*s_argument_thread).pipe_nombre_elements_attente[0]);
                     close((*s_argument_thread).pipe_interruptions[0]);                      close((*s_argument_thread).pipe_interruptions[0]);
                     close((*s_argument_thread)  
                             .pipe_nombre_interruptions_attente[0]);  
   
                     if (pthread_mutex_unlock(&((*s_argument_thread)                      if (pthread_mutex_unlock(&((*s_argument_thread)
                             .mutex_nombre_references)) != 0)                              .mutex_nombre_references)) != 0)
Line 613  liberation_threads(struct_processus *s_e Line 796  liberation_threads(struct_processus *s_e
                 }                  }
             }              }
   
             liberation_arbre_variables(s_etat_processus,              // ne peut être effacé qu'une seule fois
                     (*s_etat_processus).s_arbre_variables, d_faux);  
   
             for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)  
             {  
                 pthread_mutex_trylock(&((*(*s_etat_processus)  
                         .s_liste_variables_statiques[i].objet).mutex));  
                 pthread_mutex_unlock(&((*(*s_etat_processus)  
                         .s_liste_variables_statiques[i].objet).mutex));  
   
                 liberation(s_etat_processus, (*s_etat_processus)  
                         .s_liste_variables_statiques[i].objet);  
                 free((*s_etat_processus).s_liste_variables_statiques[i].nom);  
             }  
   
             free((*s_etat_processus).s_liste_variables_statiques);  
   
             // Ne peut être effacé qu'une seule fois  
             if (suppression_variables_partagees == d_faux)              if (suppression_variables_partagees == d_faux)
             {              {
                 suppression_variables_partagees = d_vrai;                  suppression_variables_partagees = d_vrai;
   
                 for(i = 0; i < (*(*s_etat_processus)                  liberation_arbre_variables_partagees(s_etat_processus,
                         .s_liste_variables_partagees).nombre_variables; i++)                          (*(*s_etat_processus).s_arbre_variables_partagees));
                 {  
                     pthread_mutex_trylock(&((*(*(*s_etat_processus)  
                             .s_liste_variables_partagees).table[i].objet)  
                             .mutex));  
                     pthread_mutex_unlock(&((*(*(*s_etat_processus)  
                             .s_liste_variables_partagees).table[i].objet)  
                             .mutex));  
   
                     liberation(s_etat_processus, (*(*s_etat_processus)                  l_element_partage_courant = (*(*s_etat_processus)
                             .s_liste_variables_partagees).table[i].objet);                          .l_liste_variables_partagees);
                     free((*(*s_etat_processus).s_liste_variables_partagees)  
                             .table[i].nom);  
                 }  
   
                 if ((*(*s_etat_processus).s_liste_variables_partagees).table                  while(l_element_partage_courant != NULL)
                         != NULL)  
                 {                  {
                     free((struct_variable_partagee *) (*(*s_etat_processus)                      l_element_partage_suivant =
                             .s_liste_variables_partagees).table);                              (*l_element_partage_courant).suivant;
                       free(l_element_partage_courant);
                       l_element_partage_courant = l_element_partage_suivant;
                 }                  }
               }
   
                 pthread_mutex_trylock(&((*(*s_etat_processus)              liberation_arbre_variables(s_etat_processus,
                         .s_liste_variables_partagees).mutex));                      (*s_etat_processus).s_arbre_variables, d_faux);
                 pthread_mutex_unlock(&((*(*s_etat_processus)  
                         .s_liste_variables_partagees).mutex));              l_element_statique_courant = (*s_etat_processus)
                       .l_liste_variables_statiques;
   
               while(l_element_statique_courant != NULL)
               {
                   l_element_statique_suivant =
                       (*l_element_statique_courant).suivant;
                   free(l_element_statique_courant);
                   l_element_statique_courant = l_element_statique_suivant;
             }              }
   
             element_courant = (*s_etat_processus).l_base_pile;              element_courant = (*s_etat_processus).l_base_pile;
Line 1171  liberation_threads(struct_processus *s_e Line 1337  liberation_threads(struct_processus *s_e
             close((*s_argument_thread).pipe_acquittement[1]);              close((*s_argument_thread).pipe_acquittement[1]);
             close((*s_argument_thread).pipe_injections[1]);              close((*s_argument_thread).pipe_injections[1]);
             close((*s_argument_thread).pipe_nombre_injections[1]);              close((*s_argument_thread).pipe_nombre_injections[1]);
             close((*s_argument_thread).pipe_nombre_objets_attente[0]);              close((*s_argument_thread).pipe_nombre_elements_attente[0]);
             close((*s_argument_thread).pipe_interruptions[0]);              close((*s_argument_thread).pipe_interruptions[0]);
             close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);  
   
             if (pthread_mutex_unlock(&((*s_argument_thread)              if (pthread_mutex_unlock(&((*s_argument_thread)
                     .mutex_nombre_references)) != 0)                      .mutex_nombre_references)) != 0)
Line 1231  recherche_thread(pid_t pid, pthread_t ti Line 1396  recherche_thread(pid_t pid, pthread_t ti
   
     struct_processus                            *s_etat_processus;      struct_processus                            *s_etat_processus;
   
       if (pthread_mutex_lock(&mutex_liste_threads) != 0)
       {
           return(NULL);
       }
   
     l_element_courant = liste_threads;      l_element_courant = liste_threads;
   
     while(l_element_courant != NULL)      while(l_element_courant != NULL)
Line 1251  recherche_thread(pid_t pid, pthread_t ti Line 1421  recherche_thread(pid_t pid, pthread_t ti
          * Le processus n'existe plus. On ne distribue aucun signal.           * Le processus n'existe plus. On ne distribue aucun signal.
          */           */
   
           pthread_mutex_unlock(&mutex_liste_threads);
         return(NULL);          return(NULL);
     }      }
   
     s_etat_processus = (*((struct_thread *)      s_etat_processus = (*((struct_thread *)
             (*l_element_courant).donnee)).s_etat_processus;              (*l_element_courant).donnee)).s_etat_processus;
   
       if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
       {
           return(NULL);
       }
   
     return(s_etat_processus);      return(s_etat_processus);
 }  }
   
Line 1312  recherche_thread_principal(pid_t pid) Line 1488  recherche_thread_principal(pid_t pid)
 static inline void  static inline void
 verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)  verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
 {  {
     int         semaphore;  
   
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
     if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)      if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
 #   else  #   else
Line 1324  verrouillage_gestionnaire_signaux(struct Line 1498  verrouillage_gestionnaire_signaux(struct
         return;          return;
     }      }
   
     // Il faut respecteur l'atomicité des deux opérations suivantes !  
   
     if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) != 0)  
     {  
 #       ifndef SEMAPHORES_NOMMES  
         sem_wait(&((*s_etat_processus).semaphore_fork));  
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }  
   
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
     if (sem_post(&semaphore_gestionnaires_signaux) == -1)      if (sem_post(&semaphore_gestionnaires_signaux) == -1)
 #   else  #   else
Line 1352  verrouillage_gestionnaire_signaux(struct Line 1513  verrouillage_gestionnaire_signaux(struct
         return;          return;
     }      }
   
       return;
   }
   
   static inline void
   deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
   {
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)      while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
 #   else  #   else
     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)      while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
 #   endif  #   endif
     {      {
 #       ifndef SEMAPHORES_NOMMES          if (errno != EINTR)
         sem_wait(&((*s_etat_processus).semaphore_fork));  
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Lock error !\n"));  
         return;  
     }  
   
     if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)  
     {  
 #       ifndef SEMAPHORES_NOMMES  
         sem_wait(&((*s_etat_processus).semaphore_fork));  
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }  
   
     if (semaphore == 1)  
     {  
         // Le semaphore ne peut être pris par le thread qui a appelé  
         // le gestionnaire de signal car le signal est bloqué par ce thread  
         // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que  
         // par un thread concurrent. On essaye donc de le bloquer jusqu'à  
         // ce que ce soit possible.  
   
         if (pthread_mutex_lock(&mutex_liste_threads) != 0)  
         {          {
 #           ifndef SEMAPHORES_NOMMES              BUG(1, uprintf("Unlock error !\n"));
             sem_wait(&((*s_etat_processus).semaphore_fork));  
 #           else  
             sem_wait((*s_etat_processus).semaphore_fork);  
 #           endif  
             BUG(1, uprintf("Lock error !\n"));  
             return;              return;
         }          }
     }      }
Line 1401  verrouillage_gestionnaire_signaux(struct Line 1535  verrouillage_gestionnaire_signaux(struct
     return;      return;
 }  }
   
 static inline void  /*
 deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)  ================================================================================
     Fonctions de gestion des signaux dans les threads.
   
     Lorsqu'un processus reçoit un signal, il appelle le gestionnaire de signal
     associé qui ne fait qu'envoyer au travers de write() le signal
     reçus dans un pipe. Un second thread est bloqué sur ce pipe et
     effectue le traitement adéquat pour le signal donné.
   ================================================================================
   */
   
   #define test_signal(signal) \
       if (signal_test == SIGTEST) { signal_test = signal; return; }
   
   static int          pipe_signaux;
   
   logical1
   lancement_thread_signaux(struct_processus *s_etat_processus)
 {  {
     int         semaphore;      pthread_attr_t                  attributs;
   
     // Il faut respecteur l'atomicité des deux opérations suivantes !      void                            *argument;
   
     if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) == -1)      if (pipe((*s_etat_processus).pipe_signaux) != 0)
     {      {
 #       ifndef SEMAPHORES_NOMMES          (*s_etat_processus).erreur_systeme = d_es_processus;
         sem_wait(&((*s_etat_processus).semaphore_fork));          return(d_erreur);
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      pipe_signaux = (*s_etat_processus).pipe_signaux[1];
     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)  
 #   else      if (pthread_attr_init(&attributs) != 0)
     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)  
 #   endif  
     {      {
 #       ifndef SEMAPHORES_NOMMES          (*s_etat_processus).erreur_systeme = d_es_processus;
         sem_wait(&((*s_etat_processus).semaphore_fork));          return(d_erreur);
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_attr_setdetachstate(&attributs, PTHREAD_CREATE_JOINABLE) != 0)
     while(sem_wait(&semaphore_gestionnaires_signaux) == -1)  
 #   else  
     while(sem_wait(semaphore_gestionnaires_signaux) == -1)  
 #   endif  
     {      {
         if (errno != EINTR)          (*s_etat_processus).erreur_systeme = d_es_processus;
         {          return(d_erreur);
 #           ifndef SEMAPHORES_NOMMES  
             sem_wait(&((*s_etat_processus).semaphore_fork));  
 #           else  
             sem_wait((*s_etat_processus).semaphore_fork);  
 #           endif  
             BUG(1, uprintf("Unlock error !\n"));  
             return;  
         }  
     }      }
   
     if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)      argument = (*s_etat_processus).pipe_signaux;
   
       if (pthread_create(&((*s_etat_processus).thread_signaux), &attributs,
               thread_signaux, argument) != 0)
     {      {
 #       ifndef SEMAPHORES_NOMMES          (*s_etat_processus).erreur_systeme = d_es_processus;
         sem_wait(&((*s_etat_processus).semaphore_fork));          return(d_erreur);
 #       else  
         sem_wait((*s_etat_processus).semaphore_fork);  
 #       endif  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      return(d_absence_erreur);
     while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)  }
 #   else  
     while(sem_wait((*s_etat_processus).semaphore_fork) != 0)  logical1
 #   endif  arret_thread_signaux(struct_processus *s_etat_processus)
   {
       unsigned char       signal;
       ssize_t             n;
   
       signal = (unsigned char ) (rpl_sigmax & 0xFF);
   
       do
     {      {
         if (errno != EINTR)          n = write((*s_etat_processus).pipe_signaux[1], &signal, sizeof(signal));
   
           if (n < 0)
         {          {
             BUG(1, uprintf("Unlock error !\n"));              return(d_erreur);
             return;  
         }          }
     }      } while(n != 1);
   
       pthread_join((*s_etat_processus).thread_signaux, NULL);
   
       close((*s_etat_processus).pipe_signaux[0]);
       close((*s_etat_processus).pipe_signaux[1]);
   
       return(d_absence_erreur);
   }
   
   void *
   thread_signaux(void *argument)
   {
       int                     *pipe;
   
       sigset_t                masque;
   
       struct pollfd           fds;
   
     if (semaphore == 1)      unsigned char           signal;
   
       pipe = (int *) argument;
       fds.fd = pipe[0];
       fds.events = POLLIN;
       fds.revents = 0;
   
       sigfillset(&masque);
       pthread_sigmask(SIG_BLOCK, &masque, NULL);
   
       do
     {      {
         if (pthread_mutex_unlock(&mutex_liste_threads) != 0)          if (poll(&fds, 1, -1) == -1)
         {          {
             BUG(1, uprintf("Unlock error !\n"));              pthread_exit(NULL);
             return;  
         }          }
     }  
   
     return;          read(fds.fd, &signal, 1);
 }  
   
 #define test_signal(signal) \          if (signal != (0xFF & rpl_sigmax))
     if (signal_test == SIGTEST) { signal_test = signal; return; }          {
               envoi_signal_processus(getpid(), signal);
               // Un signal SIGALRM est envoyé par le thread de surveillance
               // des signaux jusqu'à ce que les signaux soient tous traités.
           }
       } while(signal != (0xFF & rpl_sigmax));
   
       pthread_exit(NULL);
   }
   
 // Récupération des signaux  // Récupération des signaux
 // - SIGINT (arrêt au clavier)  // - SIGINT  (arrêt au clavier)
 // - SIGTERM (signal d'arrêt en provenance du système)  // - SIGTERM (signal d'arrêt en provenance du système)
   
 void  void
 interruption1(int signal)  interruption1(int signal)
 {  {
       unsigned char       signal_tronque;
   
     test_signal(signal);      test_signal(signal);
   
     switch(signal)      switch(signal)
     {      {
         case SIGINT:          case SIGINT:
             envoi_signal_processus(getpid(), rpl_sigint);              signal_tronque = (unsigned char) (rpl_sigint & 0xFF);
               write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
             break;              break;
   
         case SIGTERM:          case SIGTERM:
             envoi_signal_processus(getpid(), rpl_sigterm);              signal_tronque = (unsigned char) (rpl_sigterm & 0xFF);
               write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
             break;              break;
   
         case SIGUSR1:          case SIGUSR1:
             envoi_signal_processus(getpid(), rpl_sigalrm);              signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);
               write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
               break;
   
           default:
               // SIGALRM
             break;              break;
     }      }
   
     return;      return;
 }  }
   
   // Récupération des signaux
   // - SIGFSTP
   //
   // ATTENTION :
   // Le signal SIGFSTP provient de la mort du processus de contrôle.
   // Sous certains systèmes (Linux...), la mort du terminal de contrôle
   // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
   // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
   // non initialisée (pointeur NULL) issue de TERMIO.
   
   void
   interruption2(int signal)
   {
       unsigned char       signal_tronque;
   
       test_signal(signal);
   
       signal_tronque = (unsigned char) (rpl_sigtstp & 0xFF);
       write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
       return;
   }
   
   void
   interruption3(int signal)
   {
       // Si on passe par ici, c'est qu'il est impossible de récupérer
       // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
       // ce qu'il reste des processus orphelins.
   
       unsigned char       message_1[] = "+++System : Uncaught access violation\n"
                                   "+++System : Aborting !\n";
       unsigned char       message_2[] = "+++System : Stack overflow\n"
                                   "+++System : Aborting !\n";
   
       test_signal(signal);
   
       if (pid_processus_pere == getpid())
       {
           kill(pid_processus_pere, SIGUSR1);
       }
   
       if (signal != SIGUSR2)
       {
           write(STDERR_FILENO, message_1, strlen(message_1));
       }
       else
       {
           write(STDERR_FILENO, message_2, strlen(message_2));
       }
   
       _exit(EXIT_FAILURE);
   }
   
   // Récupération des signaux
   // - SIGHUP
   
   void
   interruption4(int signal)
   {
       unsigned char       signal_tronque;
   
       test_signal(signal);
   
       signal_tronque = (unsigned char) (rpl_sighup & 0xFF);
       write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
       return;
   }
   
   // Récupération des signaux
   // - SIGPIPE
   
   void
   interruption5(int signal)
   {
       unsigned char       message[] = "+++System : SIGPIPE\n"
                                   "+++System : Aborting !\n";
       unsigned char       signal_tronque;
   
       test_signal(signal);
   
       if (pid_processus_pere == getpid())
       {
           signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);
           write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
       }
   
       write(STDERR_FILENO, message, strlen(message));
       return;
   }
   
 inline static void  inline static void
 signal_alrm(struct_processus *s_etat_processus, pid_t pid)  signal_alrm(struct_processus *s_etat_processus, pid_t pid)
 {  {
Line 1571  inline static void Line 1834  inline static void
 signal_term(struct_processus *s_etat_processus, pid_t pid)  signal_term(struct_processus *s_etat_processus, pid_t pid)
 {  {
     struct_processus        *s_thread_principal;      struct_processus        *s_thread_principal;
     volatile sig_atomic_t   exclusion = 0;      pthread_mutex_t         exclusion = PTHREAD_MUTEX_INITIALIZER;
   
     verrouillage_gestionnaire_signaux(s_etat_processus);      verrouillage_gestionnaire_signaux(s_etat_processus);
   
Line 1593  signal_term(struct_processus *s_etat_pro Line 1856  signal_term(struct_processus *s_etat_pro
         {          {
             (*s_etat_processus).var_volatile_traitement_sigint = -1;              (*s_etat_processus).var_volatile_traitement_sigint = -1;
   
             while(exclusion == 1);              pthread_mutex_lock(&exclusion);
             exclusion = 1;  
   
             if ((*s_etat_processus).var_volatile_requete_arret == -1)              if ((*s_etat_processus).var_volatile_requete_arret == -1)
             {              {
                 deverrouillage_gestionnaire_signaux(s_etat_processus);                  deverrouillage_gestionnaire_signaux(s_etat_processus);
                 exclusion = 0;                  pthread_mutex_unlock(&exclusion);
                 return;                  return;
             }              }
   
             (*s_etat_processus).var_volatile_requete_arret = -1;              (*s_etat_processus).var_volatile_requete_arret = -1;
             (*s_etat_processus).var_volatile_alarme = -1;              (*s_etat_processus).var_volatile_alarme = -1;
   
             exclusion = 0;              pthread_mutex_unlock(&exclusion);
         }          }
     }      }
     else      else
Line 1688  signal_int(struct_processus *s_etat_proc Line 1950  signal_int(struct_processus *s_etat_proc
     return;      return;
 }  }
   
 // Récupération des signaux  
 // - SIGFSTP  
 //  
 // ATTENTION :  
 // Le signal SIGFSTP provient de la mort du processus de contrôle.  
 // Sous certains systèmes (Linux...), la mort du terminal de contrôle  
 // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres  
 // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo  
 // non initialisée (pointeur NULL) issue de TERMIO.  
   
 void  
 interruption2(int signal)  
 {  
     test_signal(signal);  
     envoi_signal_processus(getpid(), rpl_sigtstp);  
     return;  
 }  
   
 static inline void  static inline void
 signal_tstp(struct_processus *s_etat_processus, pid_t pid)  signal_tstp(struct_processus *s_etat_processus, pid_t pid)
 {  {
Line 1753  signal_tstp(struct_processus *s_etat_pro Line 1997  signal_tstp(struct_processus *s_etat_pro
     return;      return;
 }  }
   
 void  
 interruption3(int signal)  
 {  
     // Si on passe par ici, c'est qu'il est impossible de récupérer  
     // l'erreur d'accès à la mémoire. On sort donc du programme quitte à  
     // ce qu'il reste des processus orphelins.  
   
     unsigned char       message_1[] = "+++System : Uncaught access violation\n"  
                                 "+++System : Aborting !\n";  
     unsigned char       message_2[] = "+++System : Stack overflow\n"  
                                 "+++System : Aborting !\n";  
   
     test_signal(signal);  
   
     if (pid_processus_pere == getpid())  
     {  
         kill(pid_processus_pere, SIGUSR1);  
     }  
   
     if (signal != SIGUSR2)  
     {  
         write(STDERR_FILENO, message_1, strlen(message_1));  
     }  
     else  
     {  
         write(STDERR_FILENO, message_2, strlen(message_2));  
     }  
   
     _exit(EXIT_FAILURE);  
 }  
   
   
 static void  static void
 sortie_interruption_depassement_pile(void *arg1, void *arg2, void *arg3)  sortie_interruption_depassement_pile(void *arg1, void *arg2, void *arg3)
 {  {
Line 1802  sortie_interruption_depassement_pile(voi Line 2014  sortie_interruption_depassement_pile(voi
     return;      return;
 }  }
   
   
 void  void
 interruption_depassement_pile(int urgence, stackoverflow_context_t scp)  interruption_depassement_pile(int urgence, stackoverflow_context_t scp)
 {  {
Line 1820  interruption_depassement_pile(int urgenc Line 2031  interruption_depassement_pile(int urgenc
     return;      return;
 }  }
   
   
 int  int
 interruption_violation_access(void *adresse_fautive, int gravite)  interruption_violation_access(void *adresse_fautive, int gravite)
 {  {
Line 1996  signal_inject(struct_processus *s_etat_p Line 2206  signal_inject(struct_processus *s_etat_p
     return;      return;
 }  }
   
 // Récupération des signaux  
 // - SIGPIPE  
   
 void  
 interruption5(int signal)  
 {  
     unsigned char       message[] = "+++System : SIGPIPE\n"  
                                 "+++System : Aborting !\n";  
   
     test_signal(signal);  
   
     if (pid_processus_pere == getpid())  
     {  
         envoi_signal_processus(pid_processus_pere, rpl_sigalrm);  
     }  
   
     write(STDERR_FILENO, message, strlen(message));  
     return;  
 }  
   
 static inline void  static inline void
 signal_urg(struct_processus *s_etat_processus, pid_t pid)  signal_urg(struct_processus *s_etat_processus, pid_t pid)
Line 2109  signal_abort(struct_processus *s_etat_pr Line 2300  signal_abort(struct_processus *s_etat_pr
     return;      return;
 }  }
   
 // Récupération des signaux  
 // - SIGHUP  
   
 void  
 interruption4(int signal)  
 {  
     test_signal(signal);  
     envoi_signal_processus(getpid(), rpl_sighup);  
     return;  
 }  
   
 static inline void  static inline void
 signal_hup(struct_processus *s_etat_processus, pid_t pid)  signal_hup(struct_processus *s_etat_processus, pid_t pid)
Line 2135  signal_hup(struct_processus *s_etat_proc Line 2316  signal_hup(struct_processus *s_etat_proc
         return;          return;
     }      }
   
     snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),      snprintf(nom, 8 + 64 + 1, "rpl-out-%llu-%llu",
             (unsigned long) pthread_self());              (unsigned long long) getpid(),
               (unsigned long long) pthread_self());
   
     if ((fichier = fopen(nom, "w+")) != NULL)      if ((fichier = fopen(nom, "w+")) != NULL)
     {      {
Line 2245  envoi_interruptions(struct_processus *s_ Line 2427  envoi_interruptions(struct_processus *s_
         default:          default:
             if ((*s_etat_processus).langue == 'F')              if ((*s_etat_processus).langue == 'F')
             {              {
                 printf("+++System : Spurious signal (%d) !\n", signal);                  printf("+++System : Signal inconnu (%d) !\n", signal);
             }              }
             else              else
             {              {
                 printf("+++System : Signal inconnu (%d) !\n", signal);                  printf("+++System : Spurious signal (%d) !\n", signal);
             }              }
   
             break;              break;
Line 2268  scrutation_interruptions(struct_processu Line 2450  scrutation_interruptions(struct_processu
     // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à      // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à
     // écrire.      // écrire.
   
 #   ifndef SEMAPHORES_NOMMES  #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
         if (sem_trywait(&((*s_queue_signaux).semaphore)) == 0)          if (sem_trywait(&((*s_queue_signaux).semaphore)) == 0)
 #   else  #   else
         if (sem_trywait(semaphore_queue_signaux) == 0)          if (sem_trywait(semaphore_queue_signaux) == 0)
 #   endif  #   endif
     {      {
         if ((*s_queue_signaux).pointeur_lecture !=          while((*s_queue_signaux).pointeur_lecture !=
                 (*s_queue_signaux).pointeur_ecriture)                  (*s_queue_signaux).pointeur_ecriture)
         {          {
             // Il y a un signal en attente dans le segment partagé. On le              // Il y a un signal en attente dans le segment partagé. On le
Line 2287  scrutation_interruptions(struct_processu Line 2469  scrutation_interruptions(struct_processu
             (*s_queue_signaux).pointeur_lecture =              (*s_queue_signaux).pointeur_lecture =
                     ((*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)
               while(sem_wait(&((*s_queue_signaux).signalisation)) != 0)
   #           else
               while(sem_wait(semaphore_signalisation) != 0)
   #           endif
               {
                   if (errno != EINTR)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                       return;
                   }
               }
         }          }
   
 #       ifndef SEMAPHORES_NOMMES  #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
             sem_post(&((*s_queue_signaux).semaphore));              sem_post(&((*s_queue_signaux).semaphore));
 #       else  #       else
             sem_post(semaphore_queue_signaux);              sem_post(semaphore_queue_signaux);
Line 2298  scrutation_interruptions(struct_processu Line 2493  scrutation_interruptions(struct_processu
   
     // Interruptions qui arrivent depuis le groupe courant de threads.      // Interruptions qui arrivent depuis le groupe courant de threads.
   
     if (pthread_mutex_trylock(&mutex_interruptions) == 0)      if (pthread_mutex_trylock(&((*s_etat_processus).mutex_signaux)) == 0)
     {      {
         if ((*s_etat_processus).pointeur_signal_lecture !=          while((*s_etat_processus).pointeur_signal_lecture !=
                 (*s_etat_processus).pointeur_signal_ecriture)                  (*s_etat_processus).pointeur_signal_ecriture)
         {          {
             // Il y a un signal dans la queue du thread courant. On le traite.              // Il y a un signal dans la queue du thread courant. On le traite.
Line 2312  scrutation_interruptions(struct_processu Line 2507  scrutation_interruptions(struct_processu
             (*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(&((*s_queue_signaux).signalisation)) != 0)
   #           else
               while(sem_wait(semaphore_signalisation) != 0)
   #           endif
               {
                   if (errno != EINTR)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                       return;
                   }
               }
         }          }
   
         pthread_mutex_unlock(&mutex_interruptions);          pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux));
     }      }
   
     return;      return;
Line 2394  envoi_signal_processus(pid_t pid, enum s Line 2602  envoi_signal_processus(pid_t pid, enum s
 #   ifndef IPCS_SYSV  #   ifndef IPCS_SYSV
 #       ifdef SEMAPHORES_NOMMES  #       ifdef SEMAPHORES_NOMMES
             sem_t                   *semaphore;              sem_t                   *semaphore;
               sem_t                   *signalisation;
 #       endif  #       endif
 #   else  #   else
 #       ifndef OS2  #       ifndef OS2
Line 2418  envoi_signal_processus(pid_t pid, enum s Line 2627  envoi_signal_processus(pid_t pid, enum s
             return(1);              return(1);
         }          }
   
 #       ifndef SEMAPHORES_NOMMES  #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
             while(sem_wait(&((*s_queue_signaux).semaphore)) != 0)              while(sem_wait(&((*s_queue_signaux).semaphore)) != 0)
 #       else  #       else
             while(sem_wait(semaphore_queue_signaux) != 0)              while(sem_wait(semaphore_queue_signaux) != 0)
Line 2439  envoi_signal_processus(pid_t pid, enum s Line 2648  envoi_signal_processus(pid_t pid, enum s
                 ((*s_queue_signaux).pointeur_ecriture + 1)                  ((*s_queue_signaux).pointeur_ecriture + 1)
                 % LONGUEUR_QUEUE_SIGNAUX;                  % LONGUEUR_QUEUE_SIGNAUX;
   
 #       ifndef SEMAPHORES_NOMMES  #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
             if (sem_post(&((*s_queue_signaux).semaphore)) != 0)              if (sem_post(&((*s_queue_signaux).semaphore)) != 0)
 #       else  #       else
             if (sem_post(semaphore_queue_signaux) != 0)              if (sem_post(semaphore_queue_signaux) != 0)
Line 2447  envoi_signal_processus(pid_t pid, enum s Line 2656  envoi_signal_processus(pid_t pid, enum s
         {          {
             return(1);              return(1);
         }          }
   
   #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
               if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
   #       else
               if (sem_post(semaphore_signalisation) != 0)
   #       endif
           {
               return(1);
           }
     }      }
     else      else
     {      {
Line 2533  envoi_signal_processus(pid_t pid, enum s Line 2751  envoi_signal_processus(pid_t pid, enum s
                     return(1);                      return(1);
                 }                  }
   
                   if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))
                           == SEM_FAILED)
                   {
                       return(1);
                   }
   
                 while(sem_wait(semaphore) != 0)                  while(sem_wait(semaphore) != 0)
                 {                  {
                     if (errno != EINTR)                      if (errno != EINTR)
                     {                      {
                         sem_close(semaphore);                          sem_close(semaphore);
                           sem_close(signalisation);
                         return(1);                          return(1);
                     }                      }
                 }                  }
Line 2564  envoi_signal_processus(pid_t pid, enum s Line 2789  envoi_signal_processus(pid_t pid, enum s
                 {                  {
                     return(1);                      return(1);
                 }                  }
   
                   if (sem_post(&((*queue).signalisation)) != 0)
                   {
                       return(1);
                   }
 #           else  #           else
                 if (sem_post(semaphore) != 0)                  if (sem_post(semaphore) != 0)
                 {                  {
                     sem_close(semaphore);                      sem_close(semaphore);
                       sem_close(signalisation);
                     return(1);                      return(1);
                 }                  }
   
Line 2575  envoi_signal_processus(pid_t pid, enum s Line 2806  envoi_signal_processus(pid_t pid, enum s
                 {                  {
                     return(1);                      return(1);
                 }                  }
   
                   if (sem_post(signalisation) != 0)
                   {
                       sem_close(signalisation);
                       return(1);
                   }
   
                   if (sem_close(signalisation) != 0)
                   {
                       return(1);
                   }
   
 #           endif  #           endif
   
             if (munmap(queue, sizeof(struct_queue_signaux)) != 0)              if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
Line 2588  envoi_signal_processus(pid_t pid, enum s Line 2831  envoi_signal_processus(pid_t pid, enum s
                 return(1);                  return(1);
             }              }
   
               if (sem_post(&((*queue).signalisation)) != 0)
               {
                   return(1);
               }
   
 #           ifndef OS2 // SysV  #           ifndef OS2 // SysV
                 if (shmdt(queue) != 0)                  if (shmdt(queue) != 0)
                 {                  {
Line 2636  envoi_signal_thread(pthread_t tid, enum Line 2884  envoi_signal_thread(pthread_t tid, enum
         return(1);          return(1);
     }      }
   
     if (pthread_mutex_lock(&mutex_interruptions) != 0)      s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
               .s_etat_processus;
   
       if (pthread_mutex_lock(&((*s_etat_processus).mutex_signaux)) != 0)
     {      {
         pthread_mutex_unlock(&mutex_liste_threads);          pthread_mutex_unlock(&mutex_liste_threads);
         return(1);          return(1);
     }      }
   
     s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))  
             .s_etat_processus;  
   
     (*s_etat_processus).signaux_en_queue      (*s_etat_processus).signaux_en_queue
             [(*s_etat_processus).pointeur_signal_ecriture] = signal;              [(*s_etat_processus).pointeur_signal_ecriture] = signal;
     (*s_etat_processus).pointeur_signal_ecriture =      (*s_etat_processus).pointeur_signal_ecriture =
             ((*s_etat_processus).pointeur_signal_ecriture + 1)              ((*s_etat_processus).pointeur_signal_ecriture + 1)
             % LONGUEUR_QUEUE_SIGNAUX;              % LONGUEUR_QUEUE_SIGNAUX;
   
     if (pthread_mutex_unlock(&mutex_interruptions) != 0)      if (pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux)) != 0)
     {      {
         pthread_mutex_unlock(&mutex_liste_threads);          pthread_mutex_unlock(&mutex_liste_threads);
         return(1);          return(1);
Line 2662  envoi_signal_thread(pthread_t tid, enum Line 2910  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)
       {
           return(1);
       }
   #   endif
   
     return(0);      return(0);
 }  }
   
Line 2669  int Line 2929  int
 envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,  envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
         enum signaux_rpl signal)          enum signaux_rpl signal)
 {  {
     pthread_mutex_lock(&mutex_interruptions);      pthread_mutex_lock(&((*s_etat_processus_a_signaler).mutex_signaux));
     (*s_etat_processus_a_signaler).signaux_en_queue      (*s_etat_processus_a_signaler).signaux_en_queue
             [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =              [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =
             signal;              signal;
     (*s_etat_processus_a_signaler).pointeur_signal_ecriture =      (*s_etat_processus_a_signaler).pointeur_signal_ecriture =
             ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)              ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)
             % LONGUEUR_QUEUE_SIGNAUX;              % LONGUEUR_QUEUE_SIGNAUX;
     pthread_mutex_unlock(&mutex_interruptions);      pthread_mutex_unlock(&((*s_etat_processus_a_signaler).mutex_signaux));
   
   #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
       {
           return(1);
       }
   #   else
       if (sem_post(semaphore_signalisation) != 0)
       {
           return(1);
       }
   #   endif
   
     return(0);      return(0);
 }  }
Line 2698  envoi_signal_contexte(struct_processus * Line 2970  envoi_signal_contexte(struct_processus *
 void  void
 creation_queue_signaux(struct_processus *s_etat_processus)  creation_queue_signaux(struct_processus *s_etat_processus)
 {  {
       pthread_attr_t                  attributs;
   
     unsigned char                   *nom;      unsigned char                   *nom;
   
     racine_segment = (*s_etat_processus).chemin_fichiers_temporaires;      racine_segment = (*s_etat_processus).chemin_fichiers_temporaires;
Line 2746  creation_queue_signaux(struct_processus Line 3020  creation_queue_signaux(struct_processus
   
 #       ifndef SEMAPHORES_NOMMES  #       ifndef SEMAPHORES_NOMMES
             sem_init(&((*s_queue_signaux).semaphore), 1, 1);              sem_init(&((*s_queue_signaux).semaphore), 1, 1);
               sem_init(&((*s_queue_signaux).signalisation), 1, 0);
               sem_init(&((*s_queue_signaux).arret_signalisation), 1, 1);
 #       else  #       else
             if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))              if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
                     == SEM_FAILED)                      == SEM_FAILED)
Line 2753  creation_queue_signaux(struct_processus Line 3029  creation_queue_signaux(struct_processus
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                 return;                  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;
               }
 #       endif  #       endif
   
         (*s_queue_signaux).pointeur_lecture = 0;          (*s_queue_signaux).pointeur_lecture = 0;
         (*s_queue_signaux).pointeur_ecriture = 0;          (*s_queue_signaux).pointeur_ecriture = 0;
   
           (*s_queue_signaux).requete_arret = d_faux;
   
         if (msync(s_queue_signaux, sizeof(struct_queue_signaux), 0))          if (msync(s_queue_signaux, sizeof(struct_queue_signaux), 0))
         {          {
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
Line 2820  creation_queue_signaux(struct_processus Line 3112  creation_queue_signaux(struct_processus
             }              }
   
             sem_init(&((*s_queue_signaux).semaphore), 1, 1);              sem_init(&((*s_queue_signaux).semaphore), 1, 1);
               sem_init(&((*s_queue_signaux).signalisation), 1, 0);
               sem_init(&((*s_queue_signaux).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;
 #       else // OS/2  #       else // OS/2
             if ((nom = nom_segment(NULL, getpid())) == NULL)              if ((nom = nom_segment(NULL, getpid())) == NULL)
             {              {
Line 2841  creation_queue_signaux(struct_processus Line 3137  creation_queue_signaux(struct_processus
             free(nom);              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).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;
 #       endif  #       endif
 #   endif  #   endif
   
       // Lancement du thread de récupération des signaux.
   
       if (pthread_attr_init(&attributs) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
       if (pthread_attr_setdetachstate(&attributs,
               PTHREAD_CREATE_JOINABLE) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
   #   ifdef SCHED_OTHER
       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_attr_setscope(&attributs, PTHREAD_SCOPE_SYSTEM) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   #   endif
   
       if (pthread_attr_destroy(&attributs) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
       if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs,
               thread_surveillance_signaux, s_etat_processus) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
     return;      return;
 }  }
   
Line 2866  creation_queue_signaux(struct_processus Line 3218  creation_queue_signaux(struct_processus
 void  void
 liberation_queue_signaux(struct_processus *s_etat_processus)  liberation_queue_signaux(struct_processus *s_etat_processus)
 {  {
   #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       sem_wait(&((*s_queue_signaux).arret_signalisation));
   #   else
       sem_wait(semaphore_arret_signalisation);
   #   endif
   
       (*s_queue_signaux).requete_arret = d_vrai;
   
   #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       sem_post(&((*s_queue_signaux).arret_signalisation));
   #   else
       sem_post(semaphore_arret_signalisation);
   #   endif
   
       // Incrémenter le sémaphore pour être sûr de le débloquer.
   
   #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       sem_post(&((*s_queue_signaux).signalisation));
   #   else
       sem_post(semaphore_signalisation);
   #   endif
   
       pthread_join((*s_queue_signaux).thread_signaux, NULL);
   
 #   ifdef IPCS_SYSV // SystemV  #   ifdef IPCS_SYSV // SystemV
 #       ifndef OS2  #       ifndef OS2
             if (shmdt(s_queue_signaux) == -1)              if (shmdt(s_queue_signaux) == -1)
Line 2877  liberation_queue_signaux(struct_processu Line 3253  liberation_queue_signaux(struct_processu
 #       endif  #       endif
 #   else // POSIX  #   else // POSIX
 #       ifndef SEMAPHORES_NOMMES  #       ifndef SEMAPHORES_NOMMES
             sem_close(&((*s_queue_signaux).semaphore));              // Rien à faire, les sémaphores sont anonymes.
 #       else  #       else
             sem_close(semaphore_queue_signaux);              sem_close(semaphore_queue_signaux);
               sem_close(semaphore_signalisation);
               sem_close(semaphore_arret_signalisation);
 #       endif  #       endif
   
         if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)          if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
Line 2915  destruction_queue_signaux(struct_process Line 3293  destruction_queue_signaux(struct_process
         unsigned char       *nom;          unsigned char       *nom;
 #   endif  #   endif
   
   #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       sem_wait(&((*s_queue_signaux).arret_signalisation));
   #   else
       sem_wait(semaphore_arret_signalisation);
   #   endif
   
       (*s_queue_signaux).requete_arret = d_vrai;
   
   #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       sem_post(&((*s_queue_signaux).arret_signalisation));
   #   else
       sem_post(semaphore_arret_signalisation);
   #   endif
   
       // Incrémenter le sémaphore pour être sûr de le débloquer.
   
   #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
       sem_post(&((*s_queue_signaux).signalisation));
   #   else
       sem_post(semaphore_signalisation);
   #   endif
   
       pthread_join((*s_queue_signaux).thread_signaux, NULL);
   
 #   ifdef IPCS_SYSV // SystemV  #   ifdef IPCS_SYSV // SystemV
 #       ifndef OS2  #       ifndef OS2
             // Il faut commencer par éliminer le sémaphore.              // Il faut commencer par éliminer le sémaphore.
Line 2926  destruction_queue_signaux(struct_process Line 3328  destruction_queue_signaux(struct_process
             }              }
   
             unlink((*s_queue_signaux).semaphore.path);              unlink((*s_queue_signaux).semaphore.path);
               free((*s_queue_signaux).semaphore.path);
   
               if (semctl((*s_queue_signaux).signalisation.sem, 0, IPC_RMID) == -1)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               unlink((*s_queue_signaux).signalisation.path);
               free((*s_queue_signaux).signalisation.path);
   
               if (semctl((*s_queue_signaux).arret_signalisation.sem, 0, IPC_RMID)
                       == -1)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               unlink((*s_queue_signaux).arret_signalisation.path);
               free((*s_queue_signaux).arret_signalisation.path);
   
             if (shmdt(s_queue_signaux) == -1)              if (shmdt(s_queue_signaux) == -1)
             {              {
Line 2952  destruction_queue_signaux(struct_process Line 3374  destruction_queue_signaux(struct_process
             sem_close(&((*s_queue_signaux).semaphore));              sem_close(&((*s_queue_signaux).semaphore));
             sem_destroy(&((*s_queue_signaux).semaphore));              sem_destroy(&((*s_queue_signaux).semaphore));
   
               sem_close(&((*s_queue_signaux).signalisation));
               sem_destroy(&((*s_queue_signaux).signalisation));
   
               sem_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 2960  destruction_queue_signaux(struct_process Line 3388  destruction_queue_signaux(struct_process
 #       endif  #       endif
 #   else // POSIX  #   else // POSIX
 #       ifndef SEMAPHORES_NOMMES  #       ifndef SEMAPHORES_NOMMES
             sem_close(&((*s_queue_signaux).semaphore));  
             sem_destroy(&((*s_queue_signaux).semaphore));              sem_destroy(&((*s_queue_signaux).semaphore));
               sem_destroy(&((*s_queue_signaux).signalisation));
               sem_destroy(&((*s_queue_signaux).arret_signalisation));
 #       else  #       else
             sem_close(semaphore_queue_signaux);              sem_close(semaphore_queue_signaux);
             sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);              sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);
   
               sem_close(semaphore_signalisation);
               sem_destroy2(semaphore_signalisation, getpid(), SEM_SIGNALISATION);
   
               sem_close(semaphore_arret_signalisation);
               sem_destroy2(semaphore_arret_signalisation, getpid(),
                       SEM_ARRET_SIGNALISATION);
 #       endif  #       endif
   
         if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)          if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)

Removed from v.1.88  
changed lines
  Added in v.1.134


CVSweb interface <joel.bertrand@systella.fr>