Diff for /rpl/src/interruptions.c between versions 1.67 and 1.85

version 1.67, 2011/09/14 14:34:28 version 1.85, 2011/11/18 09:51:33
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.3    RPL/2 (R) version 4.1.4
   Copyright (C) 1989-2011 Dr. BERTRAND Joël    Copyright (C) 1989-2011 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
Line 57  static volatile struct_liste_chainee_vol Line 57  static volatile struct_liste_chainee_vol
         = NULL;          = NULL;
 static volatile struct_liste_chainee_volatile   *liste_threads_surveillance  static volatile struct_liste_chainee_volatile   *liste_threads_surveillance
         = NULL;          = NULL;
   static volatile int                             code_erreur_gsl = 0;
   
   unsigned char                                   *racine_segment;
   
   static pthread_mutex_t                          mutex_interruptions
           = PTHREAD_MUTEX_INITIALIZER;
   
 void  void
 modification_pid_thread_pere(struct_processus *s_etat_processus)  modification_pid_thread_pere(struct_processus *s_etat_processus)
Line 74  modification_pid_thread_pere(struct_proc Line 80  modification_pid_thread_pere(struct_proc
 void  void
 insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)  insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)
 {  {
     sigset_t                                    oldset;  
     sigset_t                                    set;  
   
     volatile struct_liste_chainee_volatile      *l_nouvel_objet;      volatile struct_liste_chainee_volatile      *l_nouvel_objet;
   
     sigfillset(&set);  
     pthread_sigmask(SIG_BLOCK, &set, &oldset);  
   
     if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))      if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
             == NULL)              == NULL)
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         sigpending(&set);  
   
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;          return;
     }      }
   
     if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)      if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         sigpending(&set);  
   
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;          return;
     }      }
Line 108  insertion_thread(struct_processus *s_eta Line 102  insertion_thread(struct_processus *s_eta
     (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =      (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
             s_etat_processus;              s_etat_processus;
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_mutex_lock(&mutex_liste_threads) != 0)
     while(sem_wait(&semaphore_liste_threads) == -1)  
 #   else  
     while(sem_wait(semaphore_liste_threads) == -1)  
 #   endif  
     {      {
         if (errno != EINTR)          (*s_etat_processus).erreur_systeme = d_es_processus;
         {          return;
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
             sigpending(&set);  
   
             (*s_etat_processus).erreur_systeme = d_es_processus;  
             return;  
         }  
     }      }
   
     (*l_nouvel_objet).suivant = liste_threads;      (*l_nouvel_objet).suivant = liste_threads;
     liste_threads = l_nouvel_objet;      liste_threads = l_nouvel_objet;
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
     if (sem_post(&semaphore_liste_threads) != 0)  
 #   else  
     if (sem_post(semaphore_liste_threads) != 0)  
 #   endif  
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         sigpending(&set);  
   
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
   
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
     sigpending(&set);  
     return;      return;
 }  }
   
Line 149  void Line 124  void
 insertion_thread_surveillance(struct_processus *s_etat_processus,  insertion_thread_surveillance(struct_processus *s_etat_processus,
         struct_descripteur_thread *s_argument_thread)          struct_descripteur_thread *s_argument_thread)
 {  {
     sigset_t                                    oldset;  
     sigset_t                                    set;  
   
     volatile struct_liste_chainee_volatile      *l_nouvel_objet;      volatile struct_liste_chainee_volatile      *l_nouvel_objet;
   
     sigfillset(&set);  
     pthread_sigmask(SIG_BLOCK, &set, &oldset);  
   
     if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))      if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
             == NULL)              == NULL)
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         sigpending(&set);  
   
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;          return;
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_mutex_lock(&mutex_liste_threads) != 0)
     while(sem_wait(&semaphore_liste_threads) == -1)  
 #   else  
     while(sem_wait(semaphore_liste_threads) == -1)  
 #   endif  
     {      {
         if (errno != EINTR)          (*s_etat_processus).erreur_systeme = d_es_processus;
         {          return;
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
             sigpending(&set);  
   
             (*s_etat_processus).erreur_systeme = d_es_processus;  
             return;  
         }  
     }      }
   
     pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references));      pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references));
Line 192  insertion_thread_surveillance(struct_pro Line 148  insertion_thread_surveillance(struct_pro
   
     liste_threads_surveillance = l_nouvel_objet;      liste_threads_surveillance = l_nouvel_objet;
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
     if (sem_post(&semaphore_liste_threads) != 0)  
 #   else  
     if (sem_post(semaphore_liste_threads) != 0)  
 #   endif  
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         sigpending(&set);  
   
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
   
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
     sigpending(&set);  
     return;      return;
 }  }
   
 void  void
 retrait_thread(struct_processus *s_etat_processus)  retrait_thread(struct_processus *s_etat_processus)
 {  {
     sigset_t                                oldset;  
     sigset_t                                set;  
   
     volatile struct_liste_chainee_volatile  *l_element_precedent;      volatile struct_liste_chainee_volatile  *l_element_precedent;
     volatile struct_liste_chainee_volatile  *l_element_courant;      volatile struct_liste_chainee_volatile  *l_element_courant;
   
     sigfillset(&set);      if (pthread_mutex_lock(&mutex_liste_threads) != 0)
     pthread_sigmask(SIG_BLOCK, &set, &oldset);  
   
 #   ifndef SEMAPHORES_NOMMES  
     while(sem_wait(&semaphore_liste_threads) == -1)  
 #   else  
     while(sem_wait(semaphore_liste_threads) == -1)  
 #   endif  
     {      {
         if (errno != EINTR)          (*s_etat_processus).erreur_systeme = d_es_processus;
         {          return;
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
             sigpending(&set);  
   
             (*s_etat_processus).erreur_systeme = d_es_processus;  
             return;  
         }  
     }      }
   
     l_element_precedent = NULL;      l_element_precedent = NULL;
Line 256  retrait_thread(struct_processus *s_etat_ Line 187  retrait_thread(struct_processus *s_etat_
   
     if (l_element_courant == NULL)      if (l_element_courant == NULL)
     {      {
 #       ifndef SEMAPHORES_NOMMES          pthread_mutex_unlock(&mutex_liste_threads);
         sem_post(&semaphore_liste_threads);  
 #       else  
         sem_post(semaphore_liste_threads);  
 #       endif  
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         sigpending(&set);  
   
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
Line 277  retrait_thread(struct_processus *s_etat_ Line 201  retrait_thread(struct_processus *s_etat_
         (*l_element_precedent).suivant = (*l_element_courant).suivant;          (*l_element_precedent).suivant = (*l_element_courant).suivant;
     }      }
   
     if (pthread_setspecific(semaphore_fork_processus_courant, NULL) != 0)      if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
   
 #       ifndef SEMAPHORES_NOMMES  
         sem_post(&semaphore_liste_threads);  
 #       else  
         sem_post(semaphore_liste_threads);  
 #       endif  
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         sigpending(&set);  
         return;  
     }  
   
 #   ifndef SEMAPHORES_NOMMES  
     if (sem_post(&semaphore_liste_threads) != 0)  
 #   else  
     if (sem_post(semaphore_liste_threads) != 0)  
 #   endif  
     {  
         (*s_etat_processus).erreur_systeme = d_es_processus;  
   
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         sigpending(&set);  
         return;          return;
     }      }
   
     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);
   
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
     sigpending(&set);  
     return;      return;
 }  }
   
Line 316  void Line 217  void
 retrait_thread_surveillance(struct_processus *s_etat_processus,  retrait_thread_surveillance(struct_processus *s_etat_processus,
         struct_descripteur_thread *s_argument_thread)          struct_descripteur_thread *s_argument_thread)
 {  {
     sigset_t                                set;  
     sigset_t                                oldset;  
   
     volatile struct_liste_chainee_volatile  *l_element_precedent;      volatile struct_liste_chainee_volatile  *l_element_precedent;
     volatile struct_liste_chainee_volatile  *l_element_courant;      volatile struct_liste_chainee_volatile  *l_element_courant;
   
     sigfillset(&set);      if (pthread_mutex_lock(&mutex_liste_threads) != 0)
     pthread_sigmask(SIG_BLOCK, &set, &oldset);  
   
 #   ifndef SEMAPHORES_NOMMES  
     while(sem_wait(&semaphore_liste_threads) == -1)  
 #   else  
     while(sem_wait(semaphore_liste_threads) == -1)  
 #   endif  
     {      {
         if (errno != EINTR)          (*s_etat_processus).erreur_systeme = d_es_processus;
         {          return;
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
             sigpending(&set);  
   
             (*s_etat_processus).erreur_systeme = d_es_processus;  
             return;  
         }  
     }      }
   
     l_element_precedent = NULL;      l_element_precedent = NULL;
Line 357  retrait_thread_surveillance(struct_proce Line 242  retrait_thread_surveillance(struct_proce
   
     if (l_element_courant == NULL)      if (l_element_courant == NULL)
     {      {
 #       ifndef SEMAPHORES_NOMMES          pthread_mutex_unlock(&mutex_liste_threads);
         sem_post(&semaphore_liste_threads);  
 #       else  
         sem_post(semaphore_liste_threads);  
 #       endif  
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         sigpending(&set);  
   
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
Line 381  retrait_thread_surveillance(struct_proce Line 259  retrait_thread_surveillance(struct_proce
     if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))      if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
             != 0)              != 0)
     {      {
 #       ifndef SEMAPHORES_NOMMES          pthread_mutex_unlock(&mutex_liste_threads);
         sem_post(&semaphore_liste_threads);  
 #       else  
         sem_post(semaphore_liste_threads);  
 #       endif  
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         sigpending(&set);  
   
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
Line 404  retrait_thread_surveillance(struct_proce Line 275  retrait_thread_surveillance(struct_proce
         if (pthread_mutex_unlock(&((*s_argument_thread)          if (pthread_mutex_unlock(&((*s_argument_thread)
                 .mutex_nombre_references)) != 0)                  .mutex_nombre_references)) != 0)
         {          {
 #           ifndef SEMAPHORES_NOMMES              pthread_mutex_unlock(&mutex_liste_threads);
             sem_post(&semaphore_liste_threads);  
 #           else  
             sem_post(semaphore_liste_threads);  
 #           endif  
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
             sigpending(&set);  
   
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
             return;              return;
         }          }
Line 425  retrait_thread_surveillance(struct_proce Line 289  retrait_thread_surveillance(struct_proce
         if (pthread_mutex_unlock(&((*s_argument_thread)          if (pthread_mutex_unlock(&((*s_argument_thread)
                 .mutex_nombre_references)) != 0)                  .mutex_nombre_references)) != 0)
         {          {
 #           ifndef SEMAPHORES_NOMMES              pthread_mutex_unlock(&mutex_liste_threads);
             sem_post(&semaphore_liste_threads);  
 #           else  
             sem_post(semaphore_liste_threads);  
 #           endif  
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
             sigpending(&set);  
   
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
             return;              return;
         }          }
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
     if (sem_post(&semaphore_liste_threads) != 0)  
 #   else  
     if (sem_post(semaphore_liste_threads) != 0)  
 #   endif  
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         sigpending(&set);  
   
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
   
     free((struct_liste_chainee_volatile *) l_element_courant);      free((struct_liste_chainee_volatile *) l_element_courant);
   
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
     sigpending(&set);  
   
     return;      return;
 }  }
   
Line 464  verrouillage_threads_concurrents(struct_ Line 310  verrouillage_threads_concurrents(struct_
 {  {
     volatile struct_liste_chainee_volatile  *l_element_courant;      volatile struct_liste_chainee_volatile  *l_element_courant;
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_mutex_lock(&mutex_liste_threads) != 0)
     while(sem_wait(&semaphore_liste_threads) == -1)  
 #   else  
     while(sem_wait(semaphore_liste_threads) == -1)  
 #   endif  
     {      {
         if (errno != EINTR)          (*s_etat_processus).erreur_systeme = d_es_processus;
         {          return;
             (*s_etat_processus).erreur_systeme = d_es_processus;  
             return;  
         }  
     }      }
   
     l_element_courant = liste_threads;      l_element_courant = liste_threads;
Line 486  verrouillage_threads_concurrents(struct_ Line 325  verrouillage_threads_concurrents(struct_
                 (*l_element_courant).donnee)).tid, pthread_self()) == 0))                  (*l_element_courant).donnee)).tid, pthread_self()) == 0))
         {          {
 #           ifndef SEMAPHORES_NOMMES  #           ifndef SEMAPHORES_NOMMES
             while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)                  while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)
                     .donnee)).s_etat_processus).semaphore_fork)) == -1)                          .donnee)).s_etat_processus).semaphore_fork)) == -1)
 #           else  #           else
             while(sem_wait((*(*((struct_thread *) (*l_element_courant)                  while(sem_wait((*(*((struct_thread *) (*l_element_courant)
                     .donnee)).s_etat_processus).semaphore_fork) == -1)                          .donnee)).s_etat_processus).semaphore_fork) == -1)
 #           endif  #           endif
             {              {
                 if (errno != EINTR)                  (*s_etat_processus).erreur_systeme = d_es_processus;
                 {                  return;
                     (*s_etat_processus).erreur_systeme = d_es_processus;  
                     return;  
                 }  
             }              }
         }          }
   
Line 521  deverrouillage_threads_concurrents(struc Line 357  deverrouillage_threads_concurrents(struc
                 (*l_element_courant).donnee)).tid, pthread_self()) == 0))                  (*l_element_courant).donnee)).tid, pthread_self()) == 0))
         {          {
 #           ifndef SEMAPHORES_NOMMES  #           ifndef SEMAPHORES_NOMMES
             if (sem_post(&((*(*((struct_thread *)                  if (sem_post(&((*(*((struct_thread *)
                     (*l_element_courant).donnee)).s_etat_processus)                          (*l_element_courant).donnee)).s_etat_processus)
                     .semaphore_fork)) != 0)                          .semaphore_fork)) != 0)
 #           else  #           else
             if (sem_post((*(*((struct_thread *)                  if (sem_post((*(*((struct_thread *)
                     (*l_element_courant).donnee)).s_etat_processus)                          (*l_element_courant).donnee)).s_etat_processus)
                     .semaphore_fork) != 0)                          .semaphore_fork) != 0)
 #           endif  #           endif
             {              {
 #               ifndef SEMAPHORES_NOMMES                  if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
                 if (sem_post(&semaphore_liste_threads) != 0)  
                 {  
                     (*s_etat_processus).erreur_systeme = d_es_processus;  
                     return;  
                 }  
 #               else  
                 if (sem_post(semaphore_liste_threads) != 0)  
                 {                  {
                     (*s_etat_processus).erreur_systeme = d_es_processus;                      (*s_etat_processus).erreur_systeme = d_es_processus;
                     return;                      return;
                 }                  }
 #               endif  
   
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                 return;                  return;
Line 552  deverrouillage_threads_concurrents(struc Line 380  deverrouillage_threads_concurrents(struc
         l_element_courant = (*l_element_courant).suivant;          l_element_courant = (*l_element_courant).suivant;
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
     if (sem_post(&semaphore_liste_threads) != 0)  
 #   else  
     if (sem_post(semaphore_liste_threads) != 0)  
 #   endif  
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
Line 570  liberation_threads(struct_processus *s_e Line 394  liberation_threads(struct_processus *s_e
 {  {
     logical1                                    suppression_variables_partagees;      logical1                                    suppression_variables_partagees;
   
     sigset_t                                    oldset;  
     sigset_t                                    set;  
   
     struct_descripteur_thread                   *s_argument_thread;      struct_descripteur_thread                   *s_argument_thread;
   
     struct_processus                            *candidat;      struct_processus                            *candidat;
Line 586  liberation_threads(struct_processus *s_e Line 407  liberation_threads(struct_processus *s_e
     volatile struct_liste_chainee_volatile      *l_element_courant;      volatile struct_liste_chainee_volatile      *l_element_courant;
     volatile struct_liste_chainee_volatile      *l_element_suivant;      volatile struct_liste_chainee_volatile      *l_element_suivant;
   
     sigfillset(&set);      if (pthread_mutex_lock(&mutex_liste_threads) == -1)
     pthread_sigmask(SIG_BLOCK, &set, &oldset);  
   
 #   ifndef SEMAPHORES_NOMMES  
     while(sem_wait(&semaphore_liste_threads) == -1)  
 #   else  
     while(sem_wait(semaphore_liste_threads) == -1)  
 #   endif  
     {      {
         if (errno != EINTR)          (*s_etat_processus).erreur_systeme = d_es_processus;
         {          return;
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
             (*s_etat_processus).erreur_systeme = d_es_processus;  
             return;  
         }  
     }      }
   
     l_element_courant = liste_threads;      l_element_courant = liste_threads;
Line 684  liberation_threads(struct_processus *s_e Line 494  liberation_threads(struct_processus *s_e
                         .mutex_nombre_references)) != 0)                          .mutex_nombre_references)) != 0)
                 {                  {
                     (*s_etat_processus).erreur_systeme = d_es_processus;                      (*s_etat_processus).erreur_systeme = d_es_processus;
                     sem_post(&semaphore_liste_threads);                      pthread_mutex_unlock(&mutex_liste_threads);
                     return;                      return;
                 }                  }
   
Line 709  liberation_threads(struct_processus *s_e Line 519  liberation_threads(struct_processus *s_e
                             .mutex_nombre_references)) != 0)                              .mutex_nombre_references)) != 0)
                     {                      {
                         (*s_etat_processus).erreur_systeme = d_es_processus;                          (*s_etat_processus).erreur_systeme = d_es_processus;
                         sem_post(&semaphore_liste_threads);                          pthread_mutex_unlock(&mutex_liste_threads);
                         return;                          return;
                     }                      }
   
Line 734  liberation_threads(struct_processus *s_e Line 544  liberation_threads(struct_processus *s_e
                             .mutex_nombre_references)) != 0)                              .mutex_nombre_references)) != 0)
                     {                      {
                         (*s_etat_processus).erreur_systeme = d_es_processus;                          (*s_etat_processus).erreur_systeme = d_es_processus;
                         sem_post(&semaphore_liste_threads);                          pthread_mutex_unlock(&mutex_liste_threads);
                         return;                          return;
                     }                      }
                 }                  }
Line 1311  liberation_threads(struct_processus *s_e Line 1121  liberation_threads(struct_processus *s_e
             liberation_allocateur(s_etat_processus);              liberation_allocateur(s_etat_processus);
   
 #           ifndef SEMAPHORES_NOMMES  #           ifndef SEMAPHORES_NOMMES
             sem_post(&((*s_etat_processus).semaphore_fork));                  sem_post(&((*s_etat_processus).semaphore_fork));
             sem_destroy(&((*s_etat_processus).semaphore_fork));                  sem_destroy(&((*s_etat_processus).semaphore_fork));
 #           else  #           else
             sem_post((*s_etat_processus).semaphore_fork);                  sem_post((*s_etat_processus).semaphore_fork);
             sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork);                  sem_close((*s_etat_processus).semaphore_fork);
 #           endif  #           endif
   
             liberation_contexte_cas(s_etat_processus);              liberation_contexte_cas(s_etat_processus);
Line 1345  liberation_threads(struct_processus *s_e Line 1155  liberation_threads(struct_processus *s_e
                 != 0)                  != 0)
         {          {
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
             sem_post(&semaphore_liste_threads);              pthread_mutex_unlock(&mutex_liste_threads);
             return;              return;
         }          }
   
Line 1369  liberation_threads(struct_processus *s_e Line 1179  liberation_threads(struct_processus *s_e
                     .mutex_nombre_references)) != 0)                      .mutex_nombre_references)) != 0)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                 sem_post(&semaphore_liste_threads);                  pthread_mutex_unlock(&mutex_liste_threads);
                 return;                  return;
             }              }
   
Line 1393  liberation_threads(struct_processus *s_e Line 1203  liberation_threads(struct_processus *s_e
                     .mutex_nombre_references)) != 0)                      .mutex_nombre_references)) != 0)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                 sem_post(&semaphore_liste_threads);                  pthread_mutex_unlock(&mutex_liste_threads);
                 return;                  return;
             }              }
         }          }
Line 1405  liberation_threads(struct_processus *s_e Line 1215  liberation_threads(struct_processus *s_e
   
     liste_threads_surveillance = NULL;      liste_threads_surveillance = NULL;
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
     if (sem_post(&semaphore_liste_threads) != 0)  
 #   else  
     if (sem_post(semaphore_liste_threads) != 0)  
 #   endif  
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
   
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
     sigpending(&set);  
     return;      return;
 }  }
   
Line 1507  recherche_thread_principal(pid_t pid) Line 1310  recherche_thread_principal(pid_t pid)
 // les sémaphores sont déjà bloqués par un gestionnaire de signal.  // les sémaphores sont déjà bloqués par un gestionnaire de signal.
   
 static inline void  static inline void
 verrouillage_gestionnaire_signaux()  verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
 {  {
     int         semaphore;      int         semaphore;
   
     sigset_t    oldset;  #   ifndef SEMAPHORES_NOMMES
     sigset_t    set;      if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
   #   else
     sem_t       *sem;      if (sem_post((*s_etat_processus).semaphore_fork) != 0)
   #   endif
     if ((sem = pthread_getspecific(semaphore_fork_processus_courant))  
             != NULL)  
     {      {
         if (sem_post(sem) != 0)          BUG(1, uprintf("Lock error !\n"));
         {          return;
             BUG(1, uprintf("Lock error !\n"));  
             return;  
         }  
     }      }
   
     // Il faut respecteur l'atomicité des deux opérations suivantes !      // Il faut respecteur l'atomicité des deux opérations suivantes !
   
     sigfillset(&set);      if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) != 0)
     pthread_sigmask(SIG_BLOCK, &set, &oldset);  
   
 #   ifndef SEMAPHORES_NOMMES  
     while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)  
 #   else  
     while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)  
 #   endif  
     {      {
         if (errno != EINTR)  #       ifndef SEMAPHORES_NOMMES
         {          sem_wait(&((*s_etat_processus).semaphore_fork));
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  #       else
             BUG(1, uprintf("Unlock error !\n"));          sem_wait((*s_etat_processus).semaphore_fork);
             return;  #       endif
         }          BUG(1, uprintf("Unlock error !\n"));
           return;
     }      }
   
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
Line 1551  verrouillage_gestionnaire_signaux() Line 1343  verrouillage_gestionnaire_signaux()
     if (sem_post(semaphore_gestionnaires_signaux) == -1)      if (sem_post(semaphore_gestionnaires_signaux) == -1)
 #   endif  #   endif
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  #       ifndef SEMAPHORES_NOMMES
           sem_wait(&((*s_etat_processus).semaphore_fork));
   #       else
           sem_wait((*s_etat_processus).semaphore_fork);
   #       endif
         BUG(1, uprintf("Lock error !\n"));          BUG(1, uprintf("Lock error !\n"));
         return;          return;
     }      }
Line 1562  verrouillage_gestionnaire_signaux() Line 1358  verrouillage_gestionnaire_signaux()
     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)      if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
 #   endif  #   endif
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  #       ifndef SEMAPHORES_NOMMES
           sem_wait(&((*s_etat_processus).semaphore_fork));
   #       else
           sem_wait((*s_etat_processus).semaphore_fork);
   #       endif
         BUG(1, uprintf("Lock error !\n"));          BUG(1, uprintf("Lock error !\n"));
         return;          return;
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
     if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)  
 #   else  
     if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)  
 #   endif  
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  #       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"));          BUG(1, uprintf("Unlock error !\n"));
         return;          return;
     }      }
Line 1586  verrouillage_gestionnaire_signaux() Line 1386  verrouillage_gestionnaire_signaux()
         // par un thread concurrent. On essaye donc de le bloquer jusqu'à          // par un thread concurrent. On essaye donc de le bloquer jusqu'à
         // ce que ce soit possible.          // ce que ce soit possible.
   
 #       ifndef SEMAPHORES_NOMMES          if (pthread_mutex_lock(&mutex_liste_threads) != 0)
         while(sem_wait(&semaphore_liste_threads) == -1)  
 #       else  
         while(sem_wait(semaphore_liste_threads) == -1)  
 #       endif  
         {          {
             if (errno != EINTR)  #           ifndef SEMAPHORES_NOMMES
             {              sem_wait(&((*s_etat_processus).semaphore_fork));
                 pthread_sigmask(SIG_SETMASK, &oldset, NULL);  #           else
               sem_wait((*s_etat_processus).semaphore_fork);
                 while(sem_wait(sem) == -1)  #           endif
                 {              BUG(1, uprintf("Lock error !\n"));
                     if (errno != EINTR)              return;
                     {  
                         BUG(1, uprintf("Lock error !\n"));  
                         return;  
                     }  
                 }  
   
                 BUG(1, uprintf("Lock error !\n"));  
                 return;  
             }  
         }          }
     }      }
   
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
     sigpending(&set);  
   
     return;      return;
 }  }
   
 static inline void  static inline void
 deverrouillage_gestionnaire_signaux()  deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
 {  {
     int         semaphore;      int         semaphore;
   
     sem_t       *sem;  
   
     sigset_t    oldset;  
     sigset_t    set;  
   
     // Il faut respecteur l'atomicité des deux opérations suivantes !      // Il faut respecteur l'atomicité des deux opérations suivantes !
   
     sigfillset(&set);      if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) == -1)
     pthread_sigmask(SIG_BLOCK, &set, &oldset);  
   
 #   ifndef SEMAPHORES_NOMMES  
     while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)  
 #   else  
     while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)  
 #   endif  
     {      {
         if (errno != EINTR)  #       ifndef SEMAPHORES_NOMMES
         {          sem_wait(&((*s_etat_processus).semaphore_fork));
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  #       else
             BUG(1, uprintf("Unlock error !\n"));          sem_wait((*s_etat_processus).semaphore_fork);
             return;  #       endif
         }          BUG(1, uprintf("Unlock error !\n"));
           return;
     }      }
   
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
Line 1652  deverrouillage_gestionnaire_signaux() Line 1425  deverrouillage_gestionnaire_signaux()
     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)      if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
 #   endif  #   endif
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  #       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"));          BUG(1, uprintf("Unlock error !\n"));
         return;          return;
     }      }
Line 1665  deverrouillage_gestionnaire_signaux() Line 1442  deverrouillage_gestionnaire_signaux()
     {      {
         if (errno != EINTR)          if (errno != EINTR)
         {          {
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  #           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"));              BUG(1, uprintf("Unlock error !\n"));
             return;              return;
         }          }
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
     if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)  
 #   else  
     if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)  
 #   endif  
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  #       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"));          BUG(1, uprintf("Unlock error !\n"));
         return;          return;
     }      }
   
     if ((sem = pthread_getspecific(semaphore_fork_processus_courant))  #   ifndef SEMAPHORES_NOMMES
             != NULL)      while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
   #   else
       while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
   #   endif
     {      {
         while(sem_wait(sem) == -1)          if (errno != EINTR)
         {          {
             if (errno != EINTR)              BUG(1, uprintf("Unlock error !\n"));
             {              return;
                 pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
                 BUG(1, uprintf("Unlock error !\n"));  
                 return;  
             }  
         }          }
     }      }
   
     if (semaphore == 1)      if (semaphore == 1)
     {      {
 #       ifndef SEMAPHORES_NOMMES          if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
         if (sem_post(&semaphore_liste_threads) != 0)  
 #       else  
         if (sem_post(semaphore_liste_threads) != 0)  
 #       endif  
         {          {
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
   
             BUG(1, uprintf("Unlock error !\n"));              BUG(1, uprintf("Unlock error !\n"));
             return;              return;
         }          }
     }      }
   
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
     sigpending(&set);  
   
     return;      return;
 }  }
   
Line 1739  interruption1(int signal) Line 1510  interruption1(int signal)
             envoi_signal_processus(getpid(), rpl_sigterm);              envoi_signal_processus(getpid(), rpl_sigterm);
             break;              break;
   
         case SIGALRM:          case SIGUSR1:
             envoi_signal_processus(getpid(), rpl_sigalrm);              envoi_signal_processus(getpid(), rpl_sigalrm);
             break;              break;
     }      }
Line 1752  signal_alrm(struct_processus *s_etat_pro Line 1523  signal_alrm(struct_processus *s_etat_pro
 {  {
     struct_processus        *s_thread_principal;      struct_processus        *s_thread_principal;
   
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux(s_etat_processus);
   
     if (pid == getpid())      if (pid == getpid())
     {      {
Line 1792  signal_alrm(struct_processus *s_etat_pro Line 1563  signal_alrm(struct_processus *s_etat_pro
         }          }
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
Line 1802  signal_term(struct_processus *s_etat_pro Line 1573  signal_term(struct_processus *s_etat_pro
     struct_processus        *s_thread_principal;      struct_processus        *s_thread_principal;
     volatile sig_atomic_t   exclusion = 0;      volatile sig_atomic_t   exclusion = 0;
   
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux(s_etat_processus);
   
     if (pid == getpid())      if (pid == getpid())
     {      {
Line 1827  signal_term(struct_processus *s_etat_pro Line 1598  signal_term(struct_processus *s_etat_pro
   
             if ((*s_etat_processus).var_volatile_requete_arret == -1)              if ((*s_etat_processus).var_volatile_requete_arret == -1)
             {              {
                 deverrouillage_gestionnaire_signaux();                  deverrouillage_gestionnaire_signaux(s_etat_processus);
                 exclusion = 0;                  exclusion = 0;
                 return;                  return;
             }              }
Line 1847  signal_term(struct_processus *s_etat_pro Line 1618  signal_term(struct_processus *s_etat_pro
         }          }
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
Line 1857  signal_int(struct_processus *s_etat_proc Line 1628  signal_int(struct_processus *s_etat_proc
     struct_processus        *s_thread_principal;      struct_processus        *s_thread_principal;
     volatile sig_atomic_t   exclusion = 0;      volatile sig_atomic_t   exclusion = 0;
   
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux(s_etat_processus);
   
     if (pid == getpid())      if (pid == getpid())
     {      {
Line 1882  signal_int(struct_processus *s_etat_proc Line 1653  signal_int(struct_processus *s_etat_proc
   
             if ((*s_etat_processus).var_volatile_requete_arret == -1)              if ((*s_etat_processus).var_volatile_requete_arret == -1)
             {              {
                 deverrouillage_gestionnaire_signaux();                  deverrouillage_gestionnaire_signaux(s_etat_processus);
                 exclusion = 0;                  exclusion = 0;
                 return;                  return;
             }              }
Line 1913  signal_int(struct_processus *s_etat_proc Line 1684  signal_int(struct_processus *s_etat_proc
         }          }
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
Line 1940  signal_tstp(struct_processus *s_etat_pro Line 1711  signal_tstp(struct_processus *s_etat_pro
 {  {
     struct_processus        *s_thread_principal;      struct_processus        *s_thread_principal;
   
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux(s_etat_processus);
   
     if (pid == getpid())      if (pid == getpid())
     {      {
Line 1978  signal_tstp(struct_processus *s_etat_pro Line 1749  signal_tstp(struct_processus *s_etat_pro
         }          }
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
Line 1989  interruption3(int signal) Line 1760  interruption3(int signal)
     // l'erreur d'accès à la mémoire. On sort donc du programme quitte à      // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
     // ce qu'il reste des processus orphelins.      // ce qu'il reste des processus orphelins.
   
     unsigned char       message[] = "+++System : Uncaught access violation\n"      int                 ios;
   
       unsigned char       message_1[] = "+++System : Uncaught access violation\n"
                                   "+++System : Aborting !\n";
       unsigned char       message_2[] = "+++System : Stack overflow\n"
                                 "+++System : Aborting !\n";                                  "+++System : Aborting !\n";
   
     test_signal(signal);      test_signal(signal);
   
     if (pid_processus_pere == getpid())      if (pid_processus_pere == getpid())
     {      {
         kill(pid_processus_pere, SIGALRM);          kill(pid_processus_pere, SIGUSR1);
       }
   
   
       if (signal != SIGUSR2)
       {
           ios = write(STDERR_FILENO, message_1, strlen(message_1));
       }
       else
       {
           ios = write(STDERR_FILENO, message_2, strlen(message_2));
     }      }
   
     write(STDERR_FILENO, message, strlen(message));  
     _exit(EXIT_FAILURE);      _exit(EXIT_FAILURE);
 }  }
   
 #if 0  
 // Utiliser libsigsegv  static void
 void INTERRUPTION3_A_FIXER()  sortie_interruption_depassement_pile(void *arg1, void *arg2, void *arg3)
 {  {
     pthread_t               thread;      switch((*((volatile int *) arg1)))
       {
           case 1:
               longjmp(contexte_ecriture, -1);
               break;
   
     struct_processus        *s_etat_processus;          case 2:
               longjmp(contexte_impression, -1);
               break;
       }
   
     test_signal(signal);      return;
     verrouillage_gestionnaire_signaux();  }
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)  
     {  
         deverrouillage_gestionnaire_signaux();  
         return;  
     }  
   
     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)  void
   interruption_depassement_pile(int urgence, stackoverflow_context_t scp)
   {
       if ((urgence == 0) && (routine_recursive != 0))
     {      {
         printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),          // On peut tenter de récupérer le dépassement de pile. Si la variable
                 (unsigned long long) pthread_self());          // 'routine_recursive' est non nulle, on récupère l'erreur.
         fflush(stdout);  
     }  
   
     if ((*s_etat_processus).var_volatile_recursivite == -1)          sigsegv_leave_handler(sortie_interruption_depassement_pile,
     {                  (void *) &routine_recursive, NULL, NULL);
         // Segfault dans un appel de fonction récursive  
         deverrouillage_gestionnaire_signaux();  
         longjmp(contexte, -1);  
     }      }
     else  
     {  
         // Segfault dans une routine interne  
         if (strncmp(getenv("LANG"), "fr", 2) == 0)  
         {  
             printf("+++Système : Violation d'accès\n");  
         }  
         else  
         {  
             printf("+++System : Access violation\n");  
         }  
   
         fflush(stdout);  
   
         (*s_etat_processus).compteur_violation_d_acces++;  
   
         if ((*s_etat_processus).compteur_violation_d_acces > 1)      // Ici, la panique est totale et il vaut mieux quitter l'application.
         {      interruption3(SIGUSR2);
             // On vient de récupérer plus d'une erreur de segmentation      return;
             // dans le même processus ou le même thread. L'erreur n'est pas  }
             // récupérable et on sort autoritairement du programme. Il peut  
             // rester des processus orphelins en attente !  
   
             if (strncmp(getenv("LANG"), "fr", 2) == 0)  
             {  
                 printf("+++Système : Violation d'accès, tentative de "  
                         "terminaison de la tâche\n");  
                 printf("             (defauts multiples)\n");  
             }  
             else  
             {  
                 printf("+++System : Access violation, trying to kill task "  
                         "(multiple defaults)\n");  
             }  
   
             fflush(stdout);  int
   interruption_violation_access(void *adresse_fautive, int gravite)
   {
       unsigned char       message[] = "+++System : Trying to catch access "
                                   "violation\n";
   
             deverrouillage_gestionnaire_signaux();      static int          compteur_erreur = 0;
             exit(EXIT_FAILURE);      int                 ios;
         }  
         else  
         {  
             // Première erreur de segmentation. On essaie de terminer  
             // proprement le thread ou le processus. Le signal ne peut être  
             // envoyé que depuis le même processus.  
   
             if (recherche_thread_principal(getpid(), &thread) == d_vrai)      if ((gravite == 0) && (routine_recursive != 0))
             {      {
                 if (pthread_equal(thread, pthread_self()) != 0)          // Il peut s'agir d'un dépassement de pile.
                 {  
                     deverrouillage_gestionnaire_signaux();  
   
                     if ((*s_etat_processus).pid_processus_pere != getpid())          sigsegv_leave_handler(sortie_interruption_depassement_pile,
                     {                  (void *) &routine_recursive, NULL, NULL);
                         // On est dans le thread principal d'un processus.      }
   
                         longjmp(contexte_processus, -1);      // On est dans une bonne vieille violation d'accès. On essaie
                     }      // de fermer au mieux l'application.
                     else  
                     {  
                         // On est dans le thread principal du processus  
                         // père.  
   
                         longjmp(contexte_initial, -1);      compteur_erreur++;
                     }  
                 }  
                 else  
                 {  
                     // On est dans un thread fils d'un thread principal.  
   
                     deverrouillage_gestionnaire_signaux();      if (compteur_erreur >= 2)
                     longjmp(contexte_thread, -1);      {
                 }          // Erreurs multiples, on arrête l'application.
             }          interruption3(SIGSEGV);
           return(0);
       }
   
             // Là, on ramasse les miettes puisque le thread n'existe plus      ios = write(STDERR_FILENO, message, strlen(message));
             // dans la base (corruption de la mémoire).  
   
             deverrouillage_gestionnaire_signaux();      if (pid_processus_pere == getpid())
             longjmp(contexte_initial, -1);      {
         }          longjmp(contexte_initial, -1);
           return(1);
       }
       else
       {
           longjmp(contexte_processus, -1);
           return(1);
     }      }
   
     deverrouillage_gestionnaire_signaux();      // On renvoie 0 parce qu'on décline toute responsabilité quant à la
     return;      // suite des événements...
       return(0);
 }  }
 #endif  
   
 // Traitement de rpl_sigstart  // Traitement de rpl_sigstart
   
 static inline void  static inline void
 signal_start(struct_processus *s_etat_processus, pid_t pid)  signal_start(struct_processus *s_etat_processus, pid_t pid)
 {  {
     (*s_etat_processus).demarrage_fils = d_vrai;      struct_processus        *s_thread_principal;
   
       verrouillage_gestionnaire_signaux(s_etat_processus);
   
       if (pid == getpid())
       {
           (*s_etat_processus).demarrage_fils = d_vrai;
       }
       else
       {
           // Envoi d'un signal au thread maître du groupe.
   
           if ((s_thread_principal = recherche_thread_principal(getpid()))
                   != NULL)
           {
               envoi_signal_contexte(s_thread_principal, rpl_sigstart);
           }
       }
   
       deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
Line 2135  signal_start(struct_processus *s_etat_pr Line 1904  signal_start(struct_processus *s_etat_pr
 static inline void  static inline void
 signal_cont(struct_processus *s_etat_processus, pid_t pid)  signal_cont(struct_processus *s_etat_processus, pid_t pid)
 {  {
     (*s_etat_processus).redemarrage_processus = d_vrai;      struct_processus        *s_thread_principal;
   
       verrouillage_gestionnaire_signaux(s_etat_processus);
   
       if (pid == getpid())
       {
           (*s_etat_processus).redemarrage_processus = d_vrai;
       }
       else
       {
           // Envoi d'un signal au thread maître du groupe.
   
           if ((s_thread_principal = recherche_thread_principal(getpid()))
                   != NULL)
           {
               envoi_signal_contexte(s_thread_principal, rpl_sigcont);
           }
       }
   
       deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
Line 2146  signal_stop(struct_processus *s_etat_pro Line 1934  signal_stop(struct_processus *s_etat_pro
 {  {
     struct_processus        *s_thread_principal;      struct_processus        *s_thread_principal;
   
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux(s_etat_processus);
   
     if (pid == getpid())      if (pid == getpid())
     {      {
         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))          if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
                 == NULL)                  == NULL)
         {          {
             deverrouillage_gestionnaire_signaux();              deverrouillage_gestionnaire_signaux(s_etat_processus);
             return;              return;
         }          }
   
         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)          if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
         {          {
             printf("[%d] RPL/SIGFSTOP (thread %llu)\n", (int) getpid(),              printf("[%d] RPL/SIGSTOP (thread %llu)\n", (int) getpid(),
                     (unsigned long long) pthread_self());                      (unsigned long long) pthread_self());
             fflush(stdout);              fflush(stdout);
         }          }
Line 2182  signal_stop(struct_processus *s_etat_pro Line 1970  signal_stop(struct_processus *s_etat_pro
     }      }
     else      else
     {      {
         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))  
                 == NULL)  
         {  
             deverrouillage_gestionnaire_signaux();  
             return;  
         }  
   
         // Envoi d'un signal au thread maître du groupe.          // Envoi d'un signal au thread maître du groupe.
   
         if ((s_thread_principal = recherche_thread_principal(getpid()))          if ((s_thread_principal = recherche_thread_principal(getpid()))
Line 2198  signal_stop(struct_processus *s_etat_pro Line 1979  signal_stop(struct_processus *s_etat_pro
         }          }
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
Line 2207  signal_stop(struct_processus *s_etat_pro Line 1988  signal_stop(struct_processus *s_etat_pro
 static inline void  static inline void
 signal_inject(struct_processus *s_etat_processus, pid_t pid)  signal_inject(struct_processus *s_etat_processus, pid_t pid)
 {  {
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux(s_etat_processus);
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)      if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
     {      {
         deverrouillage_gestionnaire_signaux();          deverrouillage_gestionnaire_signaux(s_etat_processus);
         return;          return;
     }      }
   
Line 2222  signal_inject(struct_processus *s_etat_p Line 2003  signal_inject(struct_processus *s_etat_p
         fflush(stdout);          fflush(stdout);
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
Line 2232  signal_inject(struct_processus *s_etat_p Line 2013  signal_inject(struct_processus *s_etat_p
 void  void
 interruption5(int signal)  interruption5(int signal)
 {  {
       int                 ios;
   
     unsigned char       message[] = "+++System : SIGPIPE\n"      unsigned char       message[] = "+++System : SIGPIPE\n"
                                 "+++System : Aborting !\n";                                  "+++System : Aborting !\n";
   
Line 2242  interruption5(int signal) Line 2025  interruption5(int signal)
         envoi_signal_processus(pid_processus_pere, rpl_sigalrm);          envoi_signal_processus(pid_processus_pere, rpl_sigalrm);
     }      }
   
     write(STDERR_FILENO, message, strlen(message));      ios = write(STDERR_FILENO, message, strlen(message));
     return;      return;
 }  }
   
Line 2251  signal_urg(struct_processus *s_etat_proc Line 2034  signal_urg(struct_processus *s_etat_proc
 {  {
     struct_processus        *s_thread_principal;      struct_processus        *s_thread_principal;
   
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux(s_etat_processus);
   
     if (pid == getpid())      if (pid == getpid())
     {      {
         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))          if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
                 == NULL)                  == NULL)
         {          {
             deverrouillage_gestionnaire_signaux();              deverrouillage_gestionnaire_signaux(s_etat_processus);
             return;              return;
         }          }
   
Line 2283  signal_urg(struct_processus *s_etat_proc Line 2066  signal_urg(struct_processus *s_etat_proc
         }          }
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
Line 2294  signal_abort(struct_processus *s_etat_pr Line 2077  signal_abort(struct_processus *s_etat_pr
 {  {
     struct_processus        *s_thread_principal;      struct_processus        *s_thread_principal;
   
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux(s_etat_processus);
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)      if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
     {      {
         deverrouillage_gestionnaire_signaux();          deverrouillage_gestionnaire_signaux(s_etat_processus);
         return;          return;
     }      }
   
Line 2314  signal_abort(struct_processus *s_etat_pr Line 2097  signal_abort(struct_processus *s_etat_pr
         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))          if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
                 == NULL)                  == NULL)
         {          {
             deverrouillage_gestionnaire_signaux();              deverrouillage_gestionnaire_signaux(s_etat_processus);
             return;              return;
         }          }
   
         (*s_etat_processus).arret_depuis_abort = -1;          (*s_etat_processus).arret_depuis_abort = -1;
   
         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)  
         {  
             printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),  
                     (unsigned long long) pthread_self());  
             fflush(stdout);  
         }  
   
         /*          /*
          * var_globale_traitement_retarde_stop :           * var_globale_traitement_retarde_stop :
          *  0 -> traitement immédiat           *  0 -> traitement immédiat
Line 2345  signal_abort(struct_processus *s_etat_pr Line 2121  signal_abort(struct_processus *s_etat_pr
     }      }
     else      else
     {      {
         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))  
                 == NULL)  
         {  
             deverrouillage_gestionnaire_signaux();  
             return;  
         }  
   
         (*s_etat_processus).arret_depuis_abort = -1;          (*s_etat_processus).arret_depuis_abort = -1;
   
         // Envoi d'un signal au thread maître du groupe.          // Envoi d'un signal au thread maître du groupe.
Line 2363  signal_abort(struct_processus *s_etat_pr Line 2132  signal_abort(struct_processus *s_etat_pr
         }          }
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
Line 2385  signal_hup(struct_processus *s_etat_proc Line 2154  signal_hup(struct_processus *s_etat_proc
   
     unsigned char           nom[8 + 64 + 1];      unsigned char           nom[8 + 64 + 1];
   
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux(s_etat_processus);
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)      if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
     {      {
         deverrouillage_gestionnaire_signaux();          deverrouillage_gestionnaire_signaux(s_etat_processus);
         return;          return;
     }      }
   
Line 2400  signal_hup(struct_processus *s_etat_proc Line 2169  signal_hup(struct_processus *s_etat_proc
     {      {
         fclose(fichier);          fclose(fichier);
   
         freopen(nom, "w", stdout);          stdout = freopen(nom, "w", stdout);
         freopen(nom, "w", stderr);          stderr = freopen(nom, "w", stderr);
     }      }
   
     freopen("/dev/null", "r", stdin);      stdin = freopen("/dev/null", "r", stdin);
   
     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)      if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
     {      {
         printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),          printf("[%d] RPL/SIGHUP (thread %llu)\n", (int) getpid(),
                 (unsigned long long) pthread_self());                  (unsigned long long) pthread_self());
         fflush(stdout);          fflush(stdout);
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
Line 2421  void Line 2190  void
 traitement_exceptions_gsl(const char *reason, const char *file,  traitement_exceptions_gsl(const char *reason, const char *file,
         int line, int gsl_errno)          int line, int gsl_errno)
 {  {
     struct_processus        *s_etat_processus;      code_erreur_gsl = gsl_errno;
       envoi_signal_processus(getpid(), rpl_sigexcept);
       return;
   }
   
     verrouillage_gestionnaire_signaux();  static inline void
   signal_except(struct_processus *s_etat_processus, pid_t pid)
   {
       verrouillage_gestionnaire_signaux(s_etat_processus);
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)      if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
     {      {
         deverrouillage_gestionnaire_signaux();          deverrouillage_gestionnaire_signaux(s_etat_processus);
         return;          return;
     }      }
   
     (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;      (*s_etat_processus).var_volatile_exception_gsl = code_erreur_gsl;
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
   
     return;      return;
 }  }
   
Line 2440  static inline void Line 2216  static inline void
 envoi_interruptions(struct_processus *s_etat_processus, enum signaux_rpl signal,  envoi_interruptions(struct_processus *s_etat_processus, enum signaux_rpl signal,
         pid_t pid_source)          pid_t pid_source)
 {  {
     unsigned char       message[] = "+++System : Spurious signa !\n";  
   
     switch(signal)      switch(signal)
     {      {
           case rpl_signull:
               break;
   
         case rpl_sigint:          case rpl_sigint:
             signal_int(s_etat_processus, pid_source);              signal_int(s_etat_processus, pid_source);
             break;              break;
Line 2488  envoi_interruptions(struct_processus *s_ Line 2265  envoi_interruptions(struct_processus *s_
             signal_tstp(s_etat_processus, pid_source);              signal_tstp(s_etat_processus, pid_source);
             break;              break;
   
           case rpl_sigexcept:
               signal_except(s_etat_processus, pid_source);
               break;
   
         default:          default:
             write(STDERR_FILENO, message, strlen(message));              if ((*s_etat_processus).langue == 'F')
               {
                   printf("+++System : Spurious signal (%d) !\n", signal);
               }
               else
               {
                   printf("+++System : Signal inconnu (%d) !\n", signal);
               }
   
             break;              break;
     }      }
   
Line 2502  scrutation_interruptions(struct_processu Line 2291  scrutation_interruptions(struct_processu
     // Interruptions qui arrivent sur le processus depuis un      // Interruptions qui arrivent sur le processus depuis un
     // processus externe.      // processus externe.
   
     // Interruptions qui arrivent depuis le groupe courant de threads.      // Les pointeurs de lecture pointent sur les prochains éléments
       // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à
       // écrire.
   
     if ((*s_etat_processus).pointeur_signal_lecture !=  #   ifndef SEMAPHORES_NOMMES
             (*s_etat_processus).pointeur_signal_ecriture)          if (sem_trywait(&((*s_queue_signaux).semaphore)) == 0)
   #   else
           if (sem_trywait(semaphore_queue_signaux) == 0)
   #   endif
     {      {
         // Il y a un signal dans la queue du thread courant. On le traite.          if ((*s_queue_signaux).pointeur_lecture !=
     }                  (*s_queue_signaux).pointeur_ecriture)
           {
     return;              // Il y a un signal en attente dans le segment partagé. On le
 }              // traite.
   
 int              envoi_interruptions(s_etat_processus,
 envoi_signal_processus(pid_t pid, enum signaux_rpl signal)                      (*s_queue_signaux).queue[(*s_queue_signaux)
 {                      .pointeur_lecture].signal, (*s_queue_signaux).queue
     // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en                      [(*s_queue_signaux).pointeur_lecture].pid);
     // mémoire puis d'y inscrire le signal à traiter.              (*s_queue_signaux).pointeur_lecture =
                       ((*s_queue_signaux).pointeur_lecture + 1)
                       % LONGUEUR_QUEUE_SIGNAUX;
           }
   
     return(0);  #       ifndef SEMAPHORES_NOMMES
 }              sem_post(&((*s_queue_signaux).semaphore));
   #       else
               sem_post(semaphore_queue_signaux);
   #       endif
       }
   
 int      // Interruptions qui arrivent depuis le groupe courant de threads.
 envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)  
 {  
     // Un signal est envoyé d'un thread à un autre thread du même processus.  
   
     return(0);      if (pthread_mutex_trylock(&mutex_interruptions) == 0)
 }      {
           if ((*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.
   
 int              envoi_interruptions(s_etat_processus,
 envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,                      (*s_etat_processus).signaux_en_queue
         enum signaux_rpl signal)                      [(*s_etat_processus).pointeur_signal_lecture],
 {                      getpid());
     (*s_etat_processus_a_signaler).signaux_en_queue              (*s_etat_processus).pointeur_signal_lecture =
             [(*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1] =                      ((*s_etat_processus).pointeur_signal_lecture + 1)
             signal;                      % LONGUEUR_QUEUE_SIGNAUX;
           }
   
     // On valide l'écriture. Cela évite l'utilisation d'un mutex.          pthread_mutex_unlock(&mutex_interruptions);
       }
   
     (*s_etat_processus_a_signaler).pointeur_signal_ecriture++;      return;
     return(0);  
 }  }
   
   
 /*  /*
 ================================================================================  ================================================================================
   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 2599  nom_segment(unsigned char *chemin, pid_t Line 2401  nom_segment(unsigned char *chemin, pid_t
   
 /*  /*
 ================================================================================  ================================================================================
   Fonction créant un segment de mémoire partagée destiné à contenir    Fonctions d'envoi d'un signal à un thread ou à un processus.
   la queue des signaux.  
 ================================================================================  ================================================================================
   Entrée : structure de description du processus    Entrée : processus et signal
 --------------------------------------------------------------------------------  --------------------------------------------------------------------------------
   Sortie : Néant    Sortie : erreur
 --------------------------------------------------------------------------------  --------------------------------------------------------------------------------
   Effet de bord : Néant    Effet de bord : Néant
 ================================================================================  ================================================================================
 */  */
   
 void  int
 creation_queue_signaux(struct_processus *s_etat_processus)  envoi_signal_processus(pid_t pid, enum signaux_rpl signal)
 {  {
     int                             segment;  #   ifndef OS2
           int                         segment;
   #   endif
   
   #   ifndef IPCS_SYSV
   #       ifdef SEMAPHORES_NOMMES
               sem_t                   *semaphore;
   #       endif
   #   else
   #       ifndef OS2
               int                     desc;
               key_t                   clef;
   #       endif
   #   endif
   
     pthread_mutexattr_t             attributs_mutex;      struct_queue_signaux            *queue;
   
     unsigned char                   *nom;      unsigned char                   *nom;
   
 #   ifndef IPCS_SYSV // POSIX      // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en
       // mémoire puis d'y inscrire le signal à traiter.
   
     if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,      if (pid == getpid())
             getpid())) == NULL)  
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          // Le signal est envoyé au même processus.
         return;  
     }  
   
     if ((segment = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,          if (s_queue_signaux == NULL)
             S_IRUSR | S_IWUSR)) == -1)          {
     {              return(1);
         free(nom);          }
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;  
         return;  
     }  
   
     if (ftruncate(segment, sizeof(struct_queue_signaux)) == -1)  #       ifndef SEMAPHORES_NOMMES
     {              while(sem_wait(&((*s_queue_signaux).semaphore)) != 0)
         free(nom);  #       else
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              while(sem_wait(semaphore_queue_signaux) != 0)
         return;  #       endif
     }          {
               if (errno != EINTR)
               {
                   return(1);
               }
           }
   
     s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),          (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
             PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0);                  .pid = pid;
     close(segment);          (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
                   .signal = signal;
   
     if (((void *) s_queue_signaux) == ((void *) -1))          (*s_queue_signaux).pointeur_ecriture =
     {                  ((*s_queue_signaux).pointeur_ecriture + 1)
         if (shm_unlink(nom) == -1)                  % LONGUEUR_QUEUE_SIGNAUX;
   
   #       ifndef SEMAPHORES_NOMMES
               if (sem_post(&((*s_queue_signaux).semaphore)) != 0)
   #       else
               if (sem_post(semaphore_queue_signaux) != 0)
   #       endif
         {          {
             free(nom);              return(1);
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;  
             return;  
         }          }
   
         free(nom);  
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;  
         return;  
     }      }
       else
       {
           // Le signal est envoyé depuis un processus distinct.
   
     free(nom);  #       ifdef IPCS_SYSV
               if ((nom = nom_segment(racine_segment, pid)) == NULL)
               {
                   return(1);
               }
   
     pthread_mutexattr_init(&attributs_mutex);  #           ifndef OS2 // SysV
     pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL);                  if ((desc = open(nom, O_RDWR)) == -1)
     pthread_mutex_init(&((*s_queue_signaux).mutex), &attributs_mutex);                  {
     pthread_mutexattr_destroy(&attributs_mutex);                      free(nom);
                       return(1);
                   }
   
     (*s_queue_signaux).pointeur_lecture = 0;                  close(desc);
     (*s_queue_signaux).pointeur_ecriture = 0;  
   
 #   else // SystemV                  if ((clef = ftok(nom, 1)) == -1)
 #   ifndef OS2                  {
                       free(nom);
                       return(1);
                   }
   
     file                            *desc;                  free(nom);
   
     key_t                           clef;                  if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0))
                           == -1)
                   {
                       return(1);
                   }
   
     // Création d'un segment de données associé au PID du processus courant                  queue = shmat(segment, NULL, 0);
   #           else // OS/2
                   if (DosGetNamedSharedMem((PVOID) &queue, nom,
                           PAG_WRITE | PAG_READ) != 0)
                   {
                       free(nom);
                       return(1);
                   }
   
     chemin = (*s_etat_processus).chemin_fichiers_temporaires;                  free(nom);
   #           endif
   #       else // POSIX
               if ((nom = nom_segment(racine_segment, pid)) == NULL)
               {
                   return(1);
               }
   
     if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,              if ((segment = shm_open(nom, O_RDWR, 0)) == -1)
             getpid())) == NULL)              {
     {                  free(nom);
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;                  return(1);
         return;              }
   
               free(nom);
   
               if ((queue = mmap(NULL, sizeof(struct_queue_signaux),
                       PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0)) ==
                       MAP_FAILED)
               {
                   close(segment);
                   return(1);
               }
   #       endif
   
               // À ce moment, le segment de mémoire partagée est projeté
               // dans l'espace du processus.
   
   #       ifndef IPCS_SYSV // POSIX
   #           ifndef SEMAPHORES_NOMMES
                   while(sem_wait(&((*queue).semaphore)) != 0)
                   {
                       if (errno != EINTR)
                       {
                           return(1);
                       }
                   }
   #           else
                   if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)
                   {
                       return(1);
                   }
   
                   while(sem_wait(semaphore) != 0)
                   {
                       if (errno != EINTR)
                       {
                           sem_close(semaphore);
                           return(1);
                       }
                   }
   #           endif
   #       else // IPCS_SYSV
               while(sem_wait(&((*queue).semaphore)) != 0)
               {
                   if (errno != EINTR)
                   {
                       return(1);
                   }
               }
   #       endif
   
           (*queue).queue[(*queue).pointeur_ecriture].pid = getpid();
           (*queue).queue[(*queue).pointeur_ecriture].signal = signal;
   
           (*queue).pointeur_ecriture = ((*queue).pointeur_ecriture + 1)
                   % LONGUEUR_QUEUE_SIGNAUX;
   
   #       ifndef IPCS_SYSV // POSIX
   #           ifndef SEMAPHORES_NOMMES
                   if (sem_post(&((*queue).semaphore)) != 0)
                   {
                       return(1);
                   }
   #           else
                   if (sem_post(semaphore) != 0)
                   {
                       sem_close(semaphore);
                       return(1);
                   }
   
                   if (sem_close(semaphore) != 0)
                   {
                       return(1);
                   }
   #           endif
   
               if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
               {
                   close(segment);
                   return(1);
               }
   #       else // IPCS_SYSV
               if (sem_post(&((*queue).semaphore)) != 0)
               {
                   return(1);
               }
   
   #           ifndef OS2 // SysV
                   if (shmdt(queue) != 0)
                   {
                       return(1);
                   }
   #           else // OS/2
                   // Pendant de DosGetNamedSHaredMem()
   #           endif
   #       endif
     }      }
   
     if ((desc = fopen(nom, "w")) == NULL)      return(0);
   }
   
   int
   envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)
   {
       // Un signal est envoyé d'un thread à un autre thread du même processus.
   
       volatile struct_liste_chainee_volatile  *l_element_courant;
   
       struct_processus                        *s_etat_processus;
   
       if (pthread_mutex_lock(&mutex_liste_threads) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;          return(1);
         return;  
     }      }
   
     fclose(desc);      l_element_courant = liste_threads;
   
     if ((clef = ftok(nom, 1)) == -1)      while(l_element_courant != NULL)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          if (((*((struct_thread *) (*l_element_courant).donnee)).pid
         return;                  == getpid()) && (pthread_equal((*((struct_thread *)
                   (*l_element_courant).donnee)).tid, tid) != 0))
           {
               break;
           }
   
           l_element_courant = (*l_element_courant).suivant;
     }      }
   
     free(nom);      if (l_element_courant == NULL)
       {
           pthread_mutex_unlock(&mutex_liste_threads);
           return(1);
       }
   
     if ((segment = shmget(clef,      if (pthread_mutex_lock(&mutex_interruptions) != 0)
             nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),  
             IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)  
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          pthread_mutex_unlock(&mutex_liste_threads);
         return;          return(1);
     }      }
   
     fifos = shmat(segment, NULL, 0);      s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
               .s_etat_processus;
   
       (*s_etat_processus).signaux_en_queue
               [(*s_etat_processus).pointeur_signal_ecriture] = signal;
       (*s_etat_processus).pointeur_signal_ecriture =
               ((*s_etat_processus).pointeur_signal_ecriture + 1)
               % LONGUEUR_QUEUE_SIGNAUX;
   
       if (pthread_mutex_unlock(&mutex_interruptions) != 0)
       {
           pthread_mutex_unlock(&mutex_liste_threads);
           return(1);
       }
   
     if (((void *) fifos) == ((void *) -1))      if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
     {      {
         if (shmctl(segment, IPC_RMID, 0) == -1)          return(1);
       }
   
       return(0);
   }
   
   int
   envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
           enum signaux_rpl signal)
   {
       pthread_mutex_lock(&mutex_interruptions);
       (*s_etat_processus_a_signaler).signaux_en_queue
               [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =
               signal;
       (*s_etat_processus_a_signaler).pointeur_signal_ecriture =
               ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)
               % LONGUEUR_QUEUE_SIGNAUX;
       pthread_mutex_unlock(&mutex_interruptions);
   
       return(0);
   }
   
   
   /*
   ================================================================================
     Fonction créant un segment de mémoire partagée destiné à contenir
     la queue des signaux.
   ================================================================================
     Entrée : structure de description du processus
   --------------------------------------------------------------------------------
     Sortie : Néant
   --------------------------------------------------------------------------------
     Effet de bord : Néant
   ================================================================================
   */
   
   void
   creation_queue_signaux(struct_processus *s_etat_processus)
   {
       unsigned char                   *nom;
   
       racine_segment = (*s_etat_processus).chemin_fichiers_temporaires;
   
   #   ifndef IPCS_SYSV // POSIX
           if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
                   getpid())) == NULL)
         {          {
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
             return;              return;
         }          }
   
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
         return;                  S_IRUSR | S_IWUSR)) == -1)
     }          {
               free(nom);
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
 #   else          if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)
           {
               free(nom);
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
     if ((nom = nom_segment(NULL, getpid())) == NULL)          s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),
     {                  PROT_READ | PROT_WRITE, MAP_SHARED, f_queue_signaux, 0);
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;  
         return;          if (((void *) s_queue_signaux) == ((void *) -1))
     }          {
               if (shm_unlink(nom) == -1)
               {
                   free(nom);
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               free(nom);
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
     if (DosAllocSharedMem(&ptr_os2, nom, nombre_queues *  
             ((2 * longueur_queue) + 4) * sizeof(int),  
             PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)  
     {  
         free(nom);          free(nom);
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;  
         return;  
     }  
   
     free(nom);  #       ifndef SEMAPHORES_NOMMES
     fifos = ptr_os2;              sem_init(&((*s_queue_signaux).semaphore), 1, 1);
   #       else
               if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
                       == SEM_FAILED)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   #       endif
   
 #   endif          (*s_queue_signaux).pointeur_lecture = 0;
           (*s_queue_signaux).pointeur_ecriture = 0;
   
           if (msync(s_queue_signaux, sizeof(struct_queue_signaux), 0))
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   #   else // IPCS_SYSV
   #       ifndef OS2
               int                             segment;
               int                             support;
   
               key_t                           clef;
   
               // Création d'un segment de données associé au PID du processus
               // courant
   
               if ((nom = nom_segment((*s_etat_processus)
                       .chemin_fichiers_temporaires, getpid())) == NULL)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               if ((support = open(nom, O_RDWR | O_CREAT | O_EXCL,
                       S_IRUSR | S_IWUSR)) == -1)
               {
                   (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
                   return;
               }
   
               if ((clef = ftok(nom, 1)) == -1)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               close(support);
               free(nom);
   
               if ((segment = shmget(clef, sizeof(struct_queue_signaux),
                       IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               s_queue_signaux = shmat(segment, NULL, 0);
               f_queue_signaux = segment;
   
               if (((void *) s_queue_signaux) == ((void *) -1))
               {
                   if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
                   {
                       (*s_etat_processus).erreur_systeme =
                               d_es_allocation_memoire;
                       return;
                   }
   
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               sem_init(&((*s_queue_signaux).semaphore), 1, 1);
               (*s_queue_signaux).pointeur_lecture = 0;
               (*s_queue_signaux).pointeur_ecriture = 0;
   #       else // OS/2
               if ((nom = nom_segment(NULL, getpid())) == NULL)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               if (DosAllocSharedMem((PVOID) &s_queue_signaux, nom,
                       sizeof(struct_queue_signaux),
                       PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
               {
                   free(nom);
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               free(nom);
   
               sem_init(&((*s_queue_signaux).semaphore), 1, 1);
               (*s_queue_signaux).pointeur_lecture = 0;
               (*s_queue_signaux).pointeur_ecriture = 0;
   #       endif
 #   endif  #   endif
   
     return;      return;
Line 2772  liberation_queue_signaux(struct_processu Line 2895  liberation_queue_signaux(struct_processu
 {  {
 #   ifdef IPCS_SYSV // SystemV  #   ifdef IPCS_SYSV // SystemV
 #       ifndef OS2  #       ifndef OS2
               if (shmdt(s_queue_signaux) == -1)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
 #       else // OS/2  #       else // OS/2
 #       endif  #       endif
 #   else // POSIX  #   else // POSIX
   #       ifndef SEMAPHORES_NOMMES
               sem_close(&((*s_queue_signaux).semaphore));
   #       else
               sem_close(semaphore_queue_signaux);
   #       endif
   
         if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)          if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
         {          {
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
             return;              return;
         }          }
   
           close(f_queue_signaux);
 #   endif  #   endif
   
     return;      return;
Line 2802  liberation_queue_signaux(struct_processu Line 2938  liberation_queue_signaux(struct_processu
 void  void
 destruction_queue_signaux(struct_processus *s_etat_processus)  destruction_queue_signaux(struct_processus *s_etat_processus)
 {  {
     unsigned char       *nom;  #   ifndef OS2
           unsigned char       *nom;
   #   endif
   
 #   ifdef IPCS_SYSV // SystemV  #   ifdef IPCS_SYSV // SystemV
 #   ifndef OS2  #       ifndef OS2
               // Il faut commencer par éliminer le sémaphore.
   
     if (shmdt(fifos) == -1)              if (semctl((*s_queue_signaux).semaphore.sem, 0, IPC_RMID) == -1)
     {              {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;                  (*s_etat_processus).erreur_systeme = d_es_processus;
         return;                  return;
     }              }
   
     if (shmctl(segment, IPC_RMID, 0) == -1)              unlink((*s_queue_signaux).semaphore.path);
     {  
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;  
         return;  
     }  
   
     if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,              if (shmdt(s_queue_signaux) == -1)
             getpid())) == NULL)              {
     {                  (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;                  return;
         return;              }
     }  
   
     unlink(nom);              if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
     free(nom);              {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
 #   else              if ((nom = nom_segment((*s_etat_processus)
                       .chemin_fichiers_temporaires, getpid())) == NULL)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
     if (DosFreeMem(fifos) != 0)              unlink(nom);
     {              free(nom);
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;  #       else
         return;              sem_close(&((*s_queue_signaux).semaphore));
     }              sem_destroy(&((*s_queue_signaux).semaphore));
   
 #   endif              if (DosFreeMem(s_queue_signaux) != 0)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   #       endif
 #   else // POSIX  #   else // POSIX
   #       ifndef SEMAPHORES_NOMMES
               sem_close(&((*s_queue_signaux).semaphore));
               sem_destroy(&((*s_queue_signaux).semaphore));
   #       else
               sem_close(semaphore_queue_signaux);
               sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);
   #       endif
   
     if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)          if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
     {          {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;              return;
     }          }
   
     if ((nom = nom_segment(NULL, getpid())) == NULL)          if ((nom = nom_segment(NULL, getpid())) == NULL)
     {          {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         return;              return;
     }          }
   
     if (shm_unlink(nom) != 0)          close(f_queue_signaux);
     {  
         free(nom);  
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;  
         return;  
     }  
   
     free(nom);          if (shm_unlink(nom) != 0)
           {
               free(nom);
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           free(nom);
 #   endif  #   endif
   
     return;      return;

Removed from v.1.67  
changed lines
  Added in v.1.85


CVSweb interface <joel.bertrand@systella.fr>