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

version 1.67, 2011/09/14 14:34:28 version 1.206, 2020/01/10 11:15:50
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.3    RPL/2 (R) version 4.1.32
   Copyright (C) 1989-2011 Dr. BERTRAND Joël    Copyright (C) 1989-2020 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
   
Line 52  typedef struct liste_chainee_volatile Line 52  typedef struct liste_chainee_volatile
     volatile void                           *donnee;      volatile void                           *donnee;
 } struct_liste_chainee_volatile;  } struct_liste_chainee_volatile;
   
   
 static volatile struct_liste_chainee_volatile   *liste_threads  static volatile struct_liste_chainee_volatile   *liste_threads
         = NULL;          = NULL;
 static volatile struct_liste_chainee_volatile   *liste_threads_surveillance  static volatile struct_liste_chainee_volatile   *liste_threads_surveillance
         = NULL;          = NULL;
   static volatile int                             code_erreur_gsl = 0;
   
   unsigned char                                   *racine_segment;
   
   static void *
   thread_surveillance_signaux(void *argument)
   {
       // Cette fonction est lancée dans un thread créé par processus pour
       // gérer le cas des appels système qui seraient bloqués lors de l'arrivée du
       // signal SIGUSR2. Les processus externes n'envoient plus un signal au
       // processus ou au thread à signaler mais positionnent les informations
       // nécessaires dans la queue des signaux et incrémentent le sémaphore.
       // Le sémaphore est décrémenté lorsque le signal est effectivement traité.
   
       int                                     nombre_signaux_envoyes;
   
       struct_processus                        *s_etat_processus;
   
       struct timespec                         attente;
   
       volatile struct_liste_chainee_volatile  *l_element_courant;
   
       sigset_t                                set;
   
       sigfillset(&set);
       pthread_sigmask(SIG_BLOCK, &set, NULL);
   
       s_etat_processus = (struct_processus *) argument;
   
       for(;;)
       {
           attente.tv_sec = 0;
           attente.tv_nsec = GRANULARITE_us * 1000;
   
           if (sem_wait(semaphore_signalisation) == 0)
           {
               while(sem_wait(semaphore_arret_signalisation) != 0)
               {
                   if (errno != EINTR)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                   }
               }
   
               if ((*s_queue_signaux).requete_arret == d_vrai)
               {
                   sem_post(semaphore_arret_signalisation);
                   sem_post(semaphore_signalisation);
   
                   break;
               }
   
               sem_post(semaphore_signalisation);
   
               nombre_signaux_envoyes = 0;
   
               // Dans un premier temps, on verrouille la queue des signaux
               // affectée au processus courant pour vérifier s'il y a quelque
               // chose à traiter.
   
               while(sem_wait(semaphore_queue_signaux) != 0)
               {
                   if (errno != EINTR)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                   }
               }
   
               if ((*s_queue_signaux).pointeur_lecture !=
                       (*s_queue_signaux).pointeur_ecriture)
               {
                   // Attention : raise() envoit le signal au thread appelant !
                   // kill() l'envoie au processus appelant, donc dans notre
                   // cas à un thread aléatoire du processus, ce qui nous
                   // convient tout à fait puisqu'il s'agit de débloquer les
                   // appels système lents.
   
                   nombre_signaux_envoyes++;
                   kill(getpid(), SIGUSR2);
                   sched_yield();
               }
   
               sem_post(semaphore_queue_signaux);
               sem_post(semaphore_arret_signalisation);
   
               // Dans un second temps, on balaye toutes les queues de signaux
               // des threads du processus courant.
   
               // Attention : l'ordre de verrouillage des mutexes est important
               // pour éviter les conditions bloquantes !
   
               pthread_mutex_lock(&mutex_liste_threads);
   
               l_element_courant = liste_threads;
   
               while(l_element_courant != NULL)
               {
                   if ((*((struct_thread *) (*l_element_courant).donnee)).pid
                           == getpid())
                   {
                       pthread_mutex_lock(&((*(*((struct_thread *)
                               (*l_element_courant).donnee)).s_etat_processus)
                               .mutex_signaux));
   
                       if ((*(*((struct_thread *) (*l_element_courant).donnee))
                               .s_etat_processus).pointeur_signal_ecriture !=
                               (*(*((struct_thread *) (*l_element_courant)
                               .donnee)).s_etat_processus).pointeur_signal_lecture)
                       {
                           nombre_signaux_envoyes++;
                           pthread_kill((*((struct_thread *)
                                   (*l_element_courant).donnee)).tid, SIGUSR2);
                           sched_yield();
                       }
   
                       pthread_mutex_unlock(&((*(*((struct_thread *)
                               (*l_element_courant).donnee)).s_etat_processus)
                               .mutex_signaux));
                   }
   
                   l_element_courant = (*l_element_courant).suivant;
               }
   
               pthread_mutex_unlock(&mutex_liste_threads);
   
               // Nanosleep
   
               if (nombre_signaux_envoyes > 0)
               {
                   nanosleep(&attente, NULL);
               }
           }
           else
           {
               if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
               }
           }
       }
   
       pthread_exit(NULL);
   }
   
 void  void
 modification_pid_thread_pere(struct_processus *s_etat_processus)  modification_pid_thread_pere(struct_processus *s_etat_processus)
Line 74  modification_pid_thread_pere(struct_proc Line 216  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;      int                                         ios;
     sigset_t                                    set;  
   
     volatile struct_liste_chainee_volatile      *l_nouvel_objet;      struct timespec                             attente;
   
     sigfillset(&set);      volatile struct_liste_chainee_volatile      *l_nouvel_objet;
     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 242  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      attente.tv_sec = 0;
     while(sem_wait(&semaphore_liste_threads) == -1)      attente.tv_nsec = GRANULARITE_us * 1000;
 #   else  
     while(sem_wait(semaphore_liste_threads) == -1)      while((ios = pthread_mutex_trylock(&mutex_liste_threads)) != 0)
 #   endif  
     {      {
         if (errno != EINTR)          if (ios != EBUSY)
         {          {
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);              (*s_etat_processus).erreur_systeme = d_es_processus;
             sigpending(&set);              return;
           }
   
           if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
           {
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
             return;              return;
         }          }
   
           nanosleep(&attente, NULL);
           INCR_GRANULARITE(attente.tv_nsec);
   
           while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               if (errno != EINTR)
               {
                   (*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 288  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_surveillance) != 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 312  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_surveillance) != 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;      int                                     ios;
     sigset_t                                set;  
       struct timespec                         attente;
   
     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);      attente.tv_sec = 0;
     pthread_sigmask(SIG_BLOCK, &set, &oldset);      attente.tv_nsec = GRANULARITE_us * 1000;
   
 #   ifndef SEMAPHORES_NOMMES      while((ios = pthread_mutex_trylock(&mutex_liste_threads)) != 0)
     while(sem_wait(&semaphore_liste_threads) == -1)  
 #   else  
     while(sem_wait(semaphore_liste_threads) == -1)  
 #   endif  
     {      {
         if (errno != EINTR)          if (ios != EBUSY)
         {          {
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);              (*s_etat_processus).erreur_systeme = d_es_processus;
             sigpending(&set);              return;
           }
   
           if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
           {
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
             return;              return;
         }          }
   
           nanosleep(&attente, NULL);
           INCR_GRANULARITE(attente.tv_nsec);
   
           while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               if (errno != EINTR)
               {
                   (*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 379  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 393  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;          return;
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      // Le thread ne peut plus traiter de signaux explicites. Il convient
     if (sem_post(&semaphore_liste_threads) != 0)      // alors de corriger le sémaphore pour annuler les signaux en attente.
 #   else  
     if (sem_post(semaphore_liste_threads) != 0)      while((*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus)
 #   endif              .pointeur_signal_ecriture != (*(*((struct_thread *)
               (*l_element_courant).donnee)).s_etat_processus)
               .pointeur_signal_lecture)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          while(sem_wait(semaphore_signalisation) != 0)
           {
               if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
           }
   
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);          (*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus)
         sigpending(&set);                  .pointeur_signal_lecture = ((*(*((struct_thread *)
         return;                  (*l_element_courant).donnee)).s_etat_processus)
                   .pointeur_signal_lecture + 1) % LONGUEUR_QUEUE_SIGNAUX;
     }      }
   
     free((void *) (*l_element_courant).donnee);      free((void *) (*l_element_courant).donnee);
     free((struct_liste_chainee_volatile *) l_element_courant);      free((struct_liste_chainee_volatile *) l_element_courant);
   
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
     sigpending(&set);  
     return;      return;
 }  }
   
Line 316  void Line 432  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_surveillance) != 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 457  retrait_thread_surveillance(struct_proce
   
     if (l_element_courant == NULL)      if (l_element_courant == NULL)
     {      {
 #       ifndef SEMAPHORES_NOMMES          pthread_mutex_unlock(&mutex_liste_threads_surveillance);
         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 474  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_surveillance);
         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 490  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_surveillance);
             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 504  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_surveillance);
             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_surveillance) != 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;
 }  }
   
 void  void
 verrouillage_threads_concurrents(struct_processus *s_etat_processus)  verrouillage_threads_concurrents(struct_processus *s_etat_processus)
 {  {
       int                                     ios;
   
       struct timespec                         attente;
   
     volatile struct_liste_chainee_volatile  *l_element_courant;      volatile struct_liste_chainee_volatile  *l_element_courant;
   
 #   ifndef SEMAPHORES_NOMMES      attente.tv_sec = 0;
     while(sem_wait(&semaphore_liste_threads) == -1)      attente.tv_nsec = GRANULARITE_us * 1000;
 #   else  
     while(sem_wait(semaphore_liste_threads) == -1)      while((ios = pthread_mutex_trylock(&mutex_liste_threads)) != 0)
 #   endif  
     {      {
         if (errno != EINTR)          if (ios != EBUSY)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
         {          {
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
             return;              return;
         }          }
   
           nanosleep(&attente, NULL);
           INCR_GRANULARITE(attente.tv_nsec);
   
           while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               if (errno != EINTR)
               {
                   (*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 568  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)                  if (errno != EINTR)
Line 521  deverrouillage_threads_concurrents(struc Line 603  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;                      (*s_etat_processus).erreur_systeme = d_es_processus;
                     return;                      return;
                 }                  }
 #               else  
                 if (sem_post(semaphore_liste_threads) != 0)  
                 {  
                     (*s_etat_processus).erreur_systeme = d_es_processus;  
                     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 626  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 640  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;
   
     unsigned long                               i;      struct_liste_variables_partagees            *l_element_partage_courant;
       struct_liste_variables_partagees            *l_element_partage_suivant;
   
       struct_liste_variables_statiques            *l_element_statique_courant;
       struct_liste_variables_statiques            *l_element_statique_suivant;
   
       integer8                                    i;
   
     void                                        *element_candidat;      void                                        *element_candidat;
     void                                        *element_courant;      void                                        *element_courant;
Line 586  liberation_threads(struct_processus *s_e Line 659  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 631  liberation_threads(struct_processus *s_e Line 693  liberation_threads(struct_processus *s_e
             close((*s_etat_processus).pipe_injections);              close((*s_etat_processus).pipe_injections);
             close((*s_etat_processus).pipe_nombre_injections);              close((*s_etat_processus).pipe_nombre_injections);
             close((*s_etat_processus).pipe_interruptions);              close((*s_etat_processus).pipe_interruptions);
             close((*s_etat_processus).pipe_nombre_objets_attente);              close((*s_etat_processus).pipe_nombre_elements_attente);
             close((*s_etat_processus).pipe_nombre_interruptions_attente);  
   
             liberation(s_etat_processus, (*s_etat_processus).at_exit);              liberation(s_etat_processus, (*s_etat_processus).at_exit);
   
Line 684  liberation_threads(struct_processus *s_e Line 745  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 700  liberation_threads(struct_processus *s_e Line 761  liberation_threads(struct_processus *s_e
                     close((*s_argument_thread).pipe_acquittement[1]);                      close((*s_argument_thread).pipe_acquittement[1]);
                     close((*s_argument_thread).pipe_injections[1]);                      close((*s_argument_thread).pipe_injections[1]);
                     close((*s_argument_thread).pipe_nombre_injections[1]);                      close((*s_argument_thread).pipe_nombre_injections[1]);
                     close((*s_argument_thread).pipe_nombre_objets_attente[0]);                      close((*s_argument_thread).pipe_nombre_elements_attente[0]);
                     close((*s_argument_thread).pipe_interruptions[0]);                      close((*s_argument_thread).pipe_interruptions[0]);
                     close((*s_argument_thread)  
                             .pipe_nombre_interruptions_attente[0]);  
   
                     if (pthread_mutex_unlock(&((*s_argument_thread)                      if (pthread_mutex_unlock(&((*s_argument_thread)
                             .mutex_nombre_references)) != 0)                              .mutex_nombre_references)) != 0)
                     {                      {
                         (*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 793  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 803  liberation_threads(struct_processus *s_e Line 862  liberation_threads(struct_processus *s_e
                 }                  }
             }              }
   
             liberation_arbre_variables(s_etat_processus,  
                     (*s_etat_processus).s_arbre_variables, d_faux);  
   
             for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)  
             {  
                 pthread_mutex_trylock(&((*(*s_etat_processus)  
                         .s_liste_variables_statiques[i].objet).mutex));  
                 pthread_mutex_unlock(&((*(*s_etat_processus)  
                         .s_liste_variables_statiques[i].objet).mutex));  
   
                 liberation(s_etat_processus, (*s_etat_processus)  
                         .s_liste_variables_statiques[i].objet);  
                 free((*s_etat_processus).s_liste_variables_statiques[i].nom);  
             }  
   
             free((*s_etat_processus).s_liste_variables_statiques);  
   
             // Ne peut être effacé qu'une seule fois              // Ne peut être effacé qu'une seule fois
             if (suppression_variables_partagees == d_faux)              if (suppression_variables_partagees == d_faux)
             {              {
                 suppression_variables_partagees = d_vrai;                  suppression_variables_partagees = d_vrai;
   
                 for(i = 0; i < (*(*s_etat_processus)                  liberation_arbre_variables_partagees(s_etat_processus,
                         .s_liste_variables_partagees).nombre_variables; i++)                          (*(*s_etat_processus).s_arbre_variables_partagees));
                 {                  (*(*s_etat_processus).s_arbre_variables_partagees) = NULL;
                     pthread_mutex_trylock(&((*(*(*s_etat_processus)  
                             .s_liste_variables_partagees).table[i].objet)  
                             .mutex));  
                     pthread_mutex_unlock(&((*(*(*s_etat_processus)  
                             .s_liste_variables_partagees).table[i].objet)  
                             .mutex));  
   
                     liberation(s_etat_processus, (*(*s_etat_processus)                  l_element_partage_courant = (*(*s_etat_processus)
                             .s_liste_variables_partagees).table[i].objet);                          .l_liste_variables_partagees);
                     free((*(*s_etat_processus).s_liste_variables_partagees)  
                             .table[i].nom);  
                 }  
   
                 if ((*(*s_etat_processus).s_liste_variables_partagees).table                  while(l_element_partage_courant != NULL)
                         != NULL)  
                 {                  {
                     free((struct_variable_partagee *) (*(*s_etat_processus)                      l_element_partage_suivant =
                             .s_liste_variables_partagees).table);                              (*l_element_partage_courant).suivant;
                       free(l_element_partage_courant);
                       l_element_partage_courant = l_element_partage_suivant;
                 }                  }
   
                 pthread_mutex_trylock(&((*(*s_etat_processus)                  (*(*s_etat_processus).l_liste_variables_partagees) = NULL;
                         .s_liste_variables_partagees).mutex));              }
                 pthread_mutex_unlock(&((*(*s_etat_processus)  
                         .s_liste_variables_partagees).mutex));              liberation_arbre_variables(s_etat_processus,
                       (*s_etat_processus).s_arbre_variables, d_faux);
   
               l_element_statique_courant = (*s_etat_processus)
                       .l_liste_variables_statiques;
   
               while(l_element_statique_courant != NULL)
               {
                   l_element_statique_suivant =
                       (*l_element_statique_courant).suivant;
                   free(l_element_statique_courant);
                   l_element_statique_courant = l_element_statique_suivant;
             }              }
   
             element_courant = (*s_etat_processus).l_base_pile;              element_courant = (*s_etat_processus).l_base_pile;
Line 1311  liberation_threads(struct_processus *s_e Line 1356  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);
             free(s_etat_processus);              liberation_allocateur_buffer(s_etat_processus);
               sys_free(s_etat_processus);
   
             s_etat_processus = candidat;              s_etat_processus = candidat;
         }          }
Line 1334  liberation_threads(struct_processus *s_e Line 1380  liberation_threads(struct_processus *s_e
   
     liste_threads = NULL;      liste_threads = NULL;
   
       if (pthread_mutex_unlock(&mutex_liste_threads) == -1)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
       if (pthread_mutex_lock(&mutex_liste_threads_surveillance) == -1)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
     l_element_courant = liste_threads_surveillance;      l_element_courant = liste_threads_surveillance;
   
     while(l_element_courant != NULL)      while(l_element_courant != NULL)
Line 1345  liberation_threads(struct_processus *s_e Line 1403  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_surveillance);
             return;              return;
         }          }
   
Line 1361  liberation_threads(struct_processus *s_e Line 1419  liberation_threads(struct_processus *s_e
             close((*s_argument_thread).pipe_acquittement[1]);              close((*s_argument_thread).pipe_acquittement[1]);
             close((*s_argument_thread).pipe_injections[1]);              close((*s_argument_thread).pipe_injections[1]);
             close((*s_argument_thread).pipe_nombre_injections[1]);              close((*s_argument_thread).pipe_nombre_injections[1]);
             close((*s_argument_thread).pipe_nombre_objets_attente[0]);              close((*s_argument_thread).pipe_nombre_elements_attente[0]);
             close((*s_argument_thread).pipe_interruptions[0]);              close((*s_argument_thread).pipe_interruptions[0]);
             close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);  
   
             if (pthread_mutex_unlock(&((*s_argument_thread)              if (pthread_mutex_unlock(&((*s_argument_thread)
                     .mutex_nombre_references)) != 0)                      .mutex_nombre_references)) != 0)
             {              {
                 (*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_surveillance);
                 return;                  return;
             }              }
   
Line 1393  liberation_threads(struct_processus *s_e Line 1450  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_surveillance);
                 return;                  return;
             }              }
         }          }
Line 1405  liberation_threads(struct_processus *s_e Line 1462  liberation_threads(struct_processus *s_e
   
     liste_threads_surveillance = NULL;      liste_threads_surveillance = NULL;
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_mutex_unlock(&mutex_liste_threads_surveillance) != 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 1428  recherche_thread(pid_t pid, pthread_t ti Line 1478  recherche_thread(pid_t pid, pthread_t ti
   
     struct_processus                            *s_etat_processus;      struct_processus                            *s_etat_processus;
   
       if (pthread_mutex_lock(&mutex_liste_threads) != 0)
       {
           return(NULL);
       }
   
     l_element_courant = liste_threads;      l_element_courant = liste_threads;
   
     while(l_element_courant != NULL)      while(l_element_courant != NULL)
Line 1448  recherche_thread(pid_t pid, pthread_t ti Line 1503  recherche_thread(pid_t pid, pthread_t ti
          * Le processus n'existe plus. On ne distribue aucun signal.           * Le processus n'existe plus. On ne distribue aucun signal.
          */           */
   
           pthread_mutex_unlock(&mutex_liste_threads);
         return(NULL);          return(NULL);
     }      }
   
     s_etat_processus = (*((struct_thread *)      s_etat_processus = (*((struct_thread *)
             (*l_element_courant).donnee)).s_etat_processus;              (*l_element_courant).donnee)).s_etat_processus;
   
       if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
       {
           return(NULL);
       }
   
     return(s_etat_processus);      return(s_etat_processus);
 }  }
   
Line 1507  recherche_thread_principal(pid_t pid) Line 1568  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;      return;
   
     sigset_t    oldset;  
     sigset_t    set;  
   
     sem_t       *sem;  
   
     if ((sem = pthread_getspecific(semaphore_fork_processus_courant))  #   ifndef SEMAPHORES_NOMMES
             != NULL)      if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
   #   else
       if (sem_post((*s_etat_processus).semaphore_fork) != 0)
   #   endif
     {      {
         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 !      return;
   }
   
     sigfillset(&set);  static inline void
     pthread_sigmask(SIG_BLOCK, &set, &oldset);  deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
   {
       return;
   
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
     while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)      while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
 #   else  #   else
     while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)      while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
 #   endif  #   endif
     {      {
         if (errno != EINTR)          if (errno != EINTR)
         {          {
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
             BUG(1, uprintf("Unlock error !\n"));              BUG(1, uprintf("Unlock error !\n"));
             return;              return;
         }          }
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      return;
     if (sem_post(&semaphore_gestionnaires_signaux) == -1)  }
 #   else  
     if (sem_post(semaphore_gestionnaires_signaux) == -1)  /*
 #   endif  ================================================================================
     Fonctions de gestion des signaux dans les threads.
   
     Lorsqu'un processus reçoit un signal, il appelle le gestionnaire de signal
     associé qui ne fait qu'envoyer au travers de write() le signal
     reçus dans un pipe. Un second thread est bloqué sur ce pipe et
     effectue le traitement adéquat pour le signal donné.
   ================================================================================
   */
   
   #define test_signal(signal) \
       if (signal_test == SIGTEST) { signal_test = signal; return; }
   
   static int          pipe_signaux;
   
   logical1
   lancement_thread_signaux(struct_processus *s_etat_processus)
   {
       pthread_attr_t                  attributs;
   
       if (pipe((*s_etat_processus).pipe_signaux) != 0)
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);          (*s_etat_processus).erreur_systeme = d_es_processus;
         BUG(1, uprintf("Lock error !\n"));          return(d_erreur);
         return;  
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      pipe_signaux = (*s_etat_processus).pipe_signaux[1];
     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)  
 #   else      if (pthread_attr_init(&attributs) != 0)
     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)  
 #   endif  
     {      {
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);          (*s_etat_processus).erreur_systeme = d_es_processus;
         BUG(1, uprintf("Lock error !\n"));          return(d_erreur);
         return;  
     }      }
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_attr_setdetachstate(&attributs, PTHREAD_CREATE_JOINABLE) != 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);          (*s_etat_processus).erreur_systeme = d_es_processus;
         BUG(1, uprintf("Unlock error !\n"));          return(d_erreur);
         return;  
     }      }
   
     if (semaphore == 1)      if (pthread_create(&((*s_etat_processus).thread_signaux), &attributs,
               thread_signaux, s_etat_processus) != 0)
     {      {
         // Le semaphore ne peut être pris par le thread qui a appelé          (*s_etat_processus).erreur_systeme = d_es_processus;
         // le gestionnaire de signal car le signal est bloqué par ce thread          return(d_erreur);
         // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que      }
         // par un thread concurrent. On essaye donc de le bloquer jusqu'à  
         // ce que ce soit possible.  
   
 #       ifndef SEMAPHORES_NOMMES      if (pthread_attr_destroy(&attributs) != 0)
         while(sem_wait(&semaphore_liste_threads) == -1)      {
 #       else          (*s_etat_processus).erreur_systeme = d_es_processus;
         while(sem_wait(semaphore_liste_threads) == -1)          return(d_erreur);
 #       endif      }
         {  
             if (errno != EINTR)  
             {  
                 pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
   
                 while(sem_wait(sem) == -1)      return(d_absence_erreur);
                 {  }
                     if (errno != EINTR)  
                     {  
                         BUG(1, uprintf("Lock error !\n"));  
                         return;  
                     }  
                 }  
   
                 BUG(1, uprintf("Lock error !\n"));  logical1
                 return;  arret_thread_signaux(struct_processus *s_etat_processus)
             }  {
       unsigned char       signal;
       ssize_t             n;
   
       signal = (unsigned char ) (rpl_sigmax & 0xFF);
   
       do
       {
           n = write_atomic(s_etat_processus, (*s_etat_processus).pipe_signaux[1],
                   &signal, sizeof(signal));
   
           if (n < 0)
           {
               return(d_erreur);
         }          }
     }      } while(n != 1);
   
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);      pthread_join((*s_etat_processus).thread_signaux, NULL);
     sigpending(&set);  
   
     return;      close((*s_etat_processus).pipe_signaux[1]);
       return(d_absence_erreur);
 }  }
   
 static inline void  void *
 deverrouillage_gestionnaire_signaux()  thread_signaux(void *argument)
 {  {
     int         semaphore;      int                     *pipe;
   
     sem_t       *sem;      sigset_t                masque;
   
     sigset_t    oldset;      struct pollfd           fds;
     sigset_t    set;  
   
     // Il faut respecteur l'atomicité des deux opérations suivantes !      struct_processus        *s_etat_processus;
   
     sigfillset(&set);      unsigned char           signal;
     pthread_sigmask(SIG_BLOCK, &set, &oldset);  
   
 #   ifndef SEMAPHORES_NOMMES      s_etat_processus = (struct_processus *) argument;
     while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)      pipe = (*s_etat_processus).pipe_signaux;
 #   else      fds.fd = pipe[0];
     while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)      fds.events = POLLIN;
 #   endif  
     {  
         if (errno != EINTR)  
         {  
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
             BUG(1, uprintf("Unlock error !\n"));  
             return;  
         }  
     }  
   
 #   ifndef SEMAPHORES_NOMMES      sigfillset(&masque);
     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)      pthread_sigmask(SIG_BLOCK, &masque, NULL);
 #   else  
     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)  
 #   endif  
     {  
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }  
   
 #   ifndef SEMAPHORES_NOMMES      do
     while(sem_wait(&semaphore_gestionnaires_signaux) == -1)  
 #   else  
     while(sem_wait(semaphore_gestionnaires_signaux) == -1)  
 #   endif  
     {      {
         if (errno != EINTR)          fds.revents = 0;
         {  
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
             BUG(1, uprintf("Unlock error !\n"));  
             return;  
         }  
     }  
   
 #   ifndef SEMAPHORES_NOMMES          while(poll(&fds, 1, -1) == -1)
     if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)  
 #   else  
     if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)  
 #   endif  
     {  
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }  
   
     if ((sem = pthread_getspecific(semaphore_fork_processus_courant))  
             != NULL)  
     {  
         while(sem_wait(sem) == -1)  
         {          {
             if (errno != EINTR)              if (errno != EINTR)
             {              {
                 pthread_sigmask(SIG_SETMASK, &oldset, NULL);                  close((*s_etat_processus).pipe_signaux[0]);
                 BUG(1, uprintf("Unlock error !\n"));                  pthread_exit(NULL);
                 return;  
             }              }
         }          }
     }  
   
     if (semaphore == 1)          if (read_atomic(s_etat_processus, fds.fd, &signal, 1) != 1)
     {  
 #       ifndef SEMAPHORES_NOMMES  
         if (sem_post(&semaphore_liste_threads) != 0)  
 #       else  
         if (sem_post(semaphore_liste_threads) != 0)  
 #       endif  
         {          {
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);              close((*s_etat_processus).pipe_signaux[0]);
               pthread_exit(NULL);
           }
   
             BUG(1, uprintf("Unlock error !\n"));          if (signal != (0xFF & rpl_sigmax))
             return;          {
               envoi_signal_processus(getpid(), signal, d_faux);
               // Un signal SIGUSR2 est envoyé par le thread de surveillance
               // des signaux jusqu'à ce que les signaux soient tous traités.
         }          }
     }      } while(signal != (0xFF & rpl_sigmax));
   
       close((*s_etat_processus).pipe_signaux[0]);
       pthread_exit(NULL);
   }
   
   
   static inline void
   _write(int fd, const void *buf, size_t count)
   {
       ssize_t         ios;
   
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);      while((ios = write(fd, buf, count)) == -1)
     sigpending(&set);      {
           if (errno != EINTR)
           {
               break;
           }
       }
   
     return;      return;
 }  }
   
 #define test_signal(signal) \  
     if (signal_test == SIGTEST) { signal_test = signal; return; }  
   
 // Récupération des signaux  // Récupération des signaux
 // - SIGINT (arrêt au clavier)  // - SIGINT  (arrêt au clavier)
 // - SIGTERM (signal d'arrêt en provenance du système)  // - SIGTERM (signal d'arrêt en provenance du système)
   
 void  void
 interruption1(int signal)  interruption1(int signal)
 {  {
       unsigned char       signal_tronque;
   
     test_signal(signal);      test_signal(signal);
   
     switch(signal)      switch(signal)
     {      {
         case SIGINT:          case SIGINT:
             envoi_signal_processus(getpid(), rpl_sigint);              signal_tronque = (unsigned char) (rpl_sigint & 0xFF);
               _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
             break;              break;
   
         case SIGTERM:          case SIGTERM:
             envoi_signal_processus(getpid(), rpl_sigterm);              signal_tronque = (unsigned char) (rpl_sigterm & 0xFF);
               _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
               break;
   
           case SIGUSR1:
               signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);
               _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
             break;              break;
   
         case SIGALRM:          default:
             envoi_signal_processus(getpid(), rpl_sigalrm);              // SIGUSR2
             break;              break;
     }      }
   
     return;      return;
 }  }
   
   // Récupération des signaux
   // - SIGFSTP
   //
   // ATTENTION :
   // Le signal SIGFSTP provient de la mort du processus de contrôle.
   // Sous certains systèmes (Linux...), la mort du terminal de contrôle
   // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
   // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
   // non initialisée (pointeur NULL) issue de TERMIO.
   
   void
   interruption2(int signal)
   {
       unsigned char       signal_tronque;
   
       test_signal(signal);
   
       signal_tronque = (unsigned char) (rpl_sigtstp & 0xFF);
       _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
   
       return;
   }
   
   void
   interruption3(int signal)
   {
       // Si on passe par ici, c'est qu'il est impossible de récupérer
       // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
       // ce qu'il reste des processus orphelins.
   
       unsigned char       message_1[] = "+++System : Uncaught access violation\n"
                                   "+++System : Aborting !\n";
       unsigned char       message_2[] = "+++System : Stack overflow\n"
                                   "+++System : Aborting !\n";
   
       test_signal(signal);
   
       if (pid_processus_pere == getpid())
       {
           kill(pid_processus_pere, SIGUSR1);
       }
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
       if (signal != SIGUSR2)
       {
           write(STDERR_FILENO, message_1, strlen(message_1));
       }
       else
       {
           write(STDERR_FILENO, message_2, strlen(message_2));
       }
   
   #   pragma GCC diagnostic pop
   
       _exit(EXIT_FAILURE);
   }
   
   // Récupération des signaux
   // - SIGHUP
   
   void
   interruption4(int signal)
   {
       unsigned char       signal_tronque;
   
       test_signal(signal);
   
       signal_tronque = (unsigned char) (rpl_sighup & 0xFF);
       _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
   
       return;
   }
   
   // Récupération des signaux
   // - SIGPIPE
   
   void
   interruption5(int signal)
   {
       unsigned char       message[] = "+++System : SIGPIPE\n"
                                   "+++System : Aborting !\n";
       unsigned char       signal_tronque;
   
       test_signal(signal);
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
       if (pid_processus_pere == getpid())
       {
           signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);
           _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
       }
   
       write(STDERR_FILENO, message, strlen(message));
   
   #   pragma GCC diagnostic pop
   
       return;
   }
   
 inline static void  inline static void
 signal_alrm(struct_processus *s_etat_processus, pid_t pid)  signal_alrm(struct_processus *s_etat_processus, pid_t pid)
 {  {
     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 1771  signal_alrm(struct_processus *s_etat_pro Line 1921  signal_alrm(struct_processus *s_etat_pro
         {          {
             // On n'est pas dans le processus père, on remonte le signal.              // On n'est pas dans le processus père, on remonte le signal.
             envoi_signal_processus((*s_etat_processus).pid_processus_pere,              envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                     rpl_sigalrm);                      rpl_sigalrm, d_faux);
         }          }
         else          else
         {          {
Line 1792  signal_alrm(struct_processus *s_etat_pro Line 1942  signal_alrm(struct_processus *s_etat_pro
         }          }
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
Line 1800  inline static void Line 1950  inline static void
 signal_term(struct_processus *s_etat_processus, pid_t pid)  signal_term(struct_processus *s_etat_processus, pid_t pid)
 {  {
     struct_processus        *s_thread_principal;      struct_processus        *s_thread_principal;
     volatile sig_atomic_t   exclusion = 0;      pthread_mutex_t         exclusion = PTHREAD_MUTEX_INITIALIZER;
   
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux(s_etat_processus);
   
     if (pid == getpid())      if (pid == getpid())
     {      {
Line 1816  signal_term(struct_processus *s_etat_pro Line 1966  signal_term(struct_processus *s_etat_pro
         if ((*s_etat_processus).pid_processus_pere != getpid())          if ((*s_etat_processus).pid_processus_pere != getpid())
         {          {
             envoi_signal_processus((*s_etat_processus).pid_processus_pere,              envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                     rpl_sigterm);                      rpl_sigterm, d_faux);
         }          }
         else          else
         {          {
             (*s_etat_processus).var_volatile_traitement_sigint = -1;              (*s_etat_processus).var_volatile_traitement_sigint = -1;
   
             while(exclusion == 1);              pthread_mutex_lock(&exclusion);
             exclusion = 1;  
   
             if ((*s_etat_processus).var_volatile_requete_arret == -1)              if ((*s_etat_processus).var_volatile_requete_arret == -1)
             {              {
                 deverrouillage_gestionnaire_signaux();                  deverrouillage_gestionnaire_signaux(s_etat_processus);
                 exclusion = 0;                  pthread_mutex_unlock(&exclusion);
                 return;                  return;
             }              }
   
             (*s_etat_processus).var_volatile_requete_arret = -1;              (*s_etat_processus).var_volatile_requete_arret = -1;
             (*s_etat_processus).var_volatile_alarme = -1;              (*s_etat_processus).var_volatile_alarme = -1;
   
             exclusion = 0;              pthread_mutex_unlock(&exclusion);
         }          }
     }      }
     else      else
Line 1847  signal_term(struct_processus *s_etat_pro Line 1996  signal_term(struct_processus *s_etat_pro
         }          }
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
Line 1855  inline static void Line 2004  inline static void
 signal_int(struct_processus *s_etat_processus, pid_t pid)  signal_int(struct_processus *s_etat_processus, pid_t pid)
 {  {
     struct_processus        *s_thread_principal;      struct_processus        *s_thread_principal;
     volatile sig_atomic_t   exclusion = 0;      pthread_mutex_t         exclusion = PTHREAD_MUTEX_INITIALIZER;
   
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux(s_etat_processus);
   
     if (pid == getpid())      if (pid == getpid())
     {      {
Line 1871  signal_int(struct_processus *s_etat_proc Line 2020  signal_int(struct_processus *s_etat_proc
         if ((*s_etat_processus).pid_processus_pere != getpid())          if ((*s_etat_processus).pid_processus_pere != getpid())
         {          {
             envoi_signal_processus((*s_etat_processus).pid_processus_pere,              envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                     rpl_sigint);                      rpl_sigint, d_faux);
         }          }
         else          else
         {          {
             (*s_etat_processus).var_volatile_traitement_sigint = -1;              (*s_etat_processus).var_volatile_traitement_sigint = -1;
   
             while(exclusion == 1);              pthread_mutex_lock(&exclusion);
             exclusion = 1;  
   
             if ((*s_etat_processus).var_volatile_requete_arret == -1)              if ((*s_etat_processus).var_volatile_requete_arret == -1)
             {              {
                 deverrouillage_gestionnaire_signaux();                  deverrouillage_gestionnaire_signaux(s_etat_processus);
                 exclusion = 0;                  pthread_mutex_unlock(&exclusion);
                 return;                  return;
             }              }
   
Line 1901  signal_int(struct_processus *s_etat_proc Line 2049  signal_int(struct_processus *s_etat_proc
             (*s_etat_processus).var_volatile_requete_arret = -1;              (*s_etat_processus).var_volatile_requete_arret = -1;
             (*s_etat_processus).var_volatile_alarme = -1;              (*s_etat_processus).var_volatile_alarme = -1;
   
             exclusion = 0;              pthread_mutex_unlock(&exclusion);
         }          }
     }      }
     else      else
Line 1913  signal_int(struct_processus *s_etat_proc Line 2061  signal_int(struct_processus *s_etat_proc
         }          }
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;  
 }  
   
 // Récupération des signaux  
 // - SIGFSTP  
 //  
 // ATTENTION :  
 // Le signal SIGFSTP provient de la mort du processus de contrôle.  
 // Sous certains systèmes (Linux...), la mort du terminal de contrôle  
 // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres  
 // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo  
 // non initialisée (pointeur NULL) issue de TERMIO.  
   
 void  
 interruption2(int signal)  
 {  
     test_signal(signal);  
     envoi_signal_processus(getpid(), rpl_sigtstp);  
     return;      return;
 }  }
   
Line 1940  signal_tstp(struct_processus *s_etat_pro Line 2070  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 1960  signal_tstp(struct_processus *s_etat_pro Line 2090  signal_tstp(struct_processus *s_etat_pro
         if ((*s_etat_processus).var_volatile_processus_pere == 0)          if ((*s_etat_processus).var_volatile_processus_pere == 0)
         {          {
             envoi_signal_processus((*s_etat_processus).pid_processus_pere,              envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                     rpl_sigtstp);                      rpl_sigtstp, d_faux);
         }          }
         else          else
         {          {
Line 1978  signal_tstp(struct_processus *s_etat_pro Line 2108  signal_tstp(struct_processus *s_etat_pro
         }          }
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
 void  static void
 interruption3(int signal)  sortie_interruption_depassement_pile(void *arg1, void *arg2, void *arg3)
 {  {
     // Si on passe par ici, c'est qu'il est impossible de récupérer      switch((*((volatile int *) arg1)))
     // l'erreur d'accès à la mémoire. On sort donc du programme quitte à      {
     // ce qu'il reste des processus orphelins.          case 1:
               longjmp(contexte_ecriture, -1);
               break;
   
     unsigned char       message[] = "+++System : Uncaught access violation\n"          case 2:
                                 "+++System : Aborting !\n";              longjmp(contexte_impression, -1);
               break;
       }
   
     test_signal(signal);      return;
   }
   
     if (pid_processus_pere == getpid())  #ifdef HAVE_SIGSEGV_RECOVERY
   void
   interruption_depassement_pile(int urgence, stackoverflow_context_t scp)
   {
       if ((urgence == 0) && (routine_recursive != 0))
     {      {
         kill(pid_processus_pere, SIGALRM);          // On peut tenter de récupérer le dépassement de pile. Si la variable
           // 'routine_recursive' est non nulle, on récupère l'erreur.
   
           sigsegv_leave_handler(sortie_interruption_depassement_pile,
                   (void *) &routine_recursive, NULL, NULL);
     }      }
   
     write(STDERR_FILENO, message, strlen(message));      // Ici, la panique est totale et il vaut mieux quitter l'application.
     _exit(EXIT_FAILURE);      interruption3(SIGUSR2);
       return;
 }  }
   #endif
   
 #if 0  int
 // Utiliser libsigsegv  interruption_violation_access(void *adresse_fautive, int gravite)
 void INTERRUPTION3_A_FIXER()  
 {  {
     pthread_t               thread;      unsigned char       message[] = "+++System : Trying to catch access "
                                   "violation\n";
     struct_processus        *s_etat_processus;  
   
     test_signal(signal);      static int          compteur_erreur = 0;
     verrouillage_gestionnaire_signaux();  
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)      if ((gravite == 0) && (routine_recursive != 0))
     {      {
         deverrouillage_gestionnaire_signaux();          // Il peut s'agir d'un dépassement de pile.
         return;  
   #       ifdef HAVE_SIGSEGV_RECOVERY
               sigsegv_leave_handler(sortie_interruption_depassement_pile,
                       (void *) &routine_recursive, NULL, NULL);
   #       else
               sortie_interruption_depassement_pile((void *) &routine_recursive,
                       NULL, NULL);
   #       endif
     }      }
   
     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)      // On est dans une bonne vieille violation d'accès. On essaie
       // de fermer au mieux l'application.
   
       compteur_erreur++;
   
       if (compteur_erreur >= 2)
     {      {
         printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),          // Erreurs multiples, on arrête l'application.
                 (unsigned long long) pthread_self());          interruption3(SIGSEGV);
         fflush(stdout);          return(0);
     }      }
   
     if ((*s_etat_processus).var_volatile_recursivite == -1)  #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
       write(STDERR_FILENO, message, strlen(message));
   
   #   pragma GCC diagnostic pop
   
       if (pid_processus_pere == getpid())
     {      {
         // Segfault dans un appel de fonction récursive          longjmp(contexte_initial, -1);
         deverrouillage_gestionnaire_signaux();          return(1);
         longjmp(contexte, -1);  
     }      }
     else      else
     {      {
         // Segfault dans une routine interne          longjmp(contexte_processus, -1);
         if (strncmp(getenv("LANG"), "fr", 2) == 0)          return(1);
         {      }
             printf("+++Système : Violation d'accès\n");  
         }  
         else  
         {  
             printf("+++System : Access violation\n");  
         }  
   
         fflush(stdout);      // On renvoie 0 parce qu'on décline toute responsabilité quant à la
       // suite des événements...
       return(0);
   }
   
         (*s_etat_processus).compteur_violation_d_acces++;  // Traitement de rpl_sigstart
   
         if ((*s_etat_processus).compteur_violation_d_acces > 1)  static inline void
         {  signal_start(struct_processus *s_etat_processus, pid_t pid)
             // On vient de récupérer plus d'une erreur de segmentation  {
             // dans le même processus ou le même thread. L'erreur n'est pas      struct_processus        *s_thread_principal;
             // récupérable et on sort autoritairement du programme. Il peut  
             // rester des processus orphelins en attente !  
   
             if (strncmp(getenv("LANG"), "fr", 2) == 0)      verrouillage_gestionnaire_signaux(s_etat_processus);
             {  
                 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);      if (pid == getpid())
       {
           (*s_etat_processus).demarrage_fils = d_vrai;
       }
       else
       {
           // Envoi d'un signal au thread maître du groupe.
   
             deverrouillage_gestionnaire_signaux();          if ((s_thread_principal = recherche_thread_principal(getpid()))
             exit(EXIT_FAILURE);                  != NULL)
         }  
         else  
         {          {
             // Première erreur de segmentation. On essaie de terminer              envoi_signal_contexte(s_thread_principal, rpl_sigstart);
             // 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 (pthread_equal(thread, pthread_self()) != 0)  
                 {  
                     deverrouillage_gestionnaire_signaux();  
   
                     if ((*s_etat_processus).pid_processus_pere != getpid())  
                     {  
                         // On est dans le thread principal d'un processus.  
   
                         longjmp(contexte_processus, -1);  
                     }  
                     else  
                     {  
                         // On est dans le thread principal du processus  
                         // père.  
   
                         longjmp(contexte_initial, -1);  
                     }  
                 }  
                 else  
                 {  
                     // On est dans un thread fils d'un thread principal.  
   
                     deverrouillage_gestionnaire_signaux();  
                     longjmp(contexte_thread, -1);  
                 }  
             }  
   
             // Là, on ramasse les miettes puisque le thread n'existe plus  
             // dans la base (corruption de la mémoire).  
   
             deverrouillage_gestionnaire_signaux();  
             longjmp(contexte_initial, -1);  
         }          }
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;  
 }  
 #endif  
   
 // Traitement de rpl_sigstart  
   
 static inline void  
 signal_start(struct_processus *s_etat_processus, pid_t pid)  
 {  
     (*s_etat_processus).demarrage_fils = d_vrai;  
     return;      return;
 }  }
   
Line 2135  signal_start(struct_processus *s_etat_pr Line 2237  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 2267  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()))  
                 == NULL)  
         {  
             deverrouillage_gestionnaire_signaux();  
             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 2296  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 2305  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 2314  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 2329  signal_inject(struct_processus *s_etat_p
         fflush(stdout);          fflush(stdout);
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
 // Récupération des signaux  
 // - SIGPIPE  
   
 void  
 interruption5(int signal)  
 {  
     unsigned char       message[] = "+++System : SIGPIPE\n"  
                                 "+++System : Aborting !\n";  
   
     test_signal(signal);  
   
     if (pid_processus_pere == getpid())  
     {  
         envoi_signal_processus(pid_processus_pere, rpl_sigalrm);  
     }  
   
     write(STDERR_FILENO, message, strlen(message));  
     return;  
 }  
   
 static inline void  static inline void
 signal_urg(struct_processus *s_etat_processus, pid_t pid)  signal_urg(struct_processus *s_etat_processus, pid_t pid)
 {  {
     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()))  
                 == NULL)  
         {  
             deverrouillage_gestionnaire_signaux();  
             return;  
         }  
   
         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)          if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
         {          {
             printf("[%d] RPL/SIGURG (thread %llu)\n", (int) getpid(),              printf("[%d] RPL/SIGURG (thread %llu)\n", (int) getpid(),
Line 2283  signal_urg(struct_processus *s_etat_proc Line 2364  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 2375  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 2311  signal_abort(struct_processus *s_etat_pr Line 2392  signal_abort(struct_processus *s_etat_pr
   
     if (pid == getpid())      if (pid == getpid())
     {      {
         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;
   
         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 2412  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 2423  signal_abort(struct_processus *s_etat_pr
         }          }
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux(s_etat_processus);
     return;      return;
 }  }
   
 // Récupération des signaux  
 // - SIGHUP  
   
 void  
 interruption4(int signal)  
 {  
     test_signal(signal);  
     envoi_signal_processus(getpid(), rpl_sighup);  
     return;  
 }  
   
 static inline void  static inline void
 signal_hup(struct_processus *s_etat_processus, pid_t pid)  signal_hup(struct_processus *s_etat_processus, pid_t pid)
Line 2385  signal_hup(struct_processus *s_etat_proc Line 2435  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;
     }      }
   
     snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),      snprintf(nom, 8 + 64 + 1, "rpl-out-%llu-%llu",
             (unsigned long) pthread_self());              (unsigned long long) getpid(),
               (unsigned long long) pthread_self());
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
     if ((fichier = fopen(nom, "w+")) != NULL)      if ((fichier = fopen(nom, "w+")) != NULL)
     {      {
Line 2406  signal_hup(struct_processus *s_etat_proc Line 2460  signal_hup(struct_processus *s_etat_proc
   
     freopen("/dev/null", "r", stdin);      freopen("/dev/null", "r", stdin);
   
   #   pragma GCC diagnostic pop
   
     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)      if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
     {      {
         printf("[%d] 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 2477  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, d_faux);
       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 2503  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 2552  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 : Signal inconnu (%d) !\n", signal);
               }
               else
               {
                   printf("+++System : Spurious signal (%d) !\n", signal);
               }
   
             break;              break;
     }      }
   
Line 2502  scrutation_interruptions(struct_processu Line 2578  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 !=      if (sem_trywait(semaphore_queue_signaux) == 0)
             (*s_etat_processus).pointeur_signal_ecriture)  
     {      {
         // Il y a un signal dans la queue du thread courant. On le traite.          while((*s_queue_signaux).pointeur_lecture !=
                   (*s_queue_signaux).pointeur_ecriture)
           {
               // Il y a un signal en attente dans le segment partagé. On le
               // traite.
   
               if (pthread_mutex_lock(&mutex_liste_threads) != 0)
               {
                   return;
               }
   
               envoi_interruptions(s_etat_processus,
                       (*s_queue_signaux).queue[(*s_queue_signaux)
                       .pointeur_lecture].signal, (*s_queue_signaux).queue
                       [(*s_queue_signaux).pointeur_lecture].pid);
               (*s_queue_signaux).pointeur_lecture =
                       ((*s_queue_signaux).pointeur_lecture + 1)
                       % LONGUEUR_QUEUE_SIGNAUX;
   
   #           ifndef IPCS_SYSV
               if (msync(s_queue_signaux, sizeof(s_queue_signaux),
                       MS_ASYNC | MS_INVALIDATE) != 0)
               {
                   sem_post(semaphore_queue_signaux);
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   #           endif
   
               if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
               {
                   return;
               }
   
               while(sem_wait(semaphore_signalisation) != 0)
               {
                   if (errno != EINTR)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                       return;
                   }
               }
           }
   
           sem_post(semaphore_queue_signaux);
     }      }
   
     return;      // Interruptions qui arrivent depuis le groupe courant de threads.
 }  
   
 int      if (pthread_mutex_trylock(&mutex_liste_threads) == 0)
 envoi_signal_processus(pid_t pid, enum signaux_rpl signal)      {
 {          if (pthread_mutex_trylock(&((*s_etat_processus).mutex_signaux)) == 0)
     // 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.              while((*s_etat_processus).pointeur_signal_lecture !=
                       (*s_etat_processus).pointeur_signal_ecriture)
               {
                   // Il y a un signal dans la queue du thread courant.
                   // On le traite.
   
     return(0);                  envoi_interruptions(s_etat_processus,
 }                          (*s_etat_processus).signaux_en_queue
                           [(*s_etat_processus).pointeur_signal_lecture],
                           getpid());
                   (*s_etat_processus).pointeur_signal_lecture =
                           ((*s_etat_processus).pointeur_signal_lecture + 1)
                           % LONGUEUR_QUEUE_SIGNAUX;
   
 int                  while(sem_wait(semaphore_signalisation) != 0)
 envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)                  {
 {                      if (errno != EINTR)
     // Un signal est envoyé d'un thread à un autre thread du même processus.                      {
                           if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
                           {
                               (*s_etat_processus).erreur_systeme = d_es_processus;
                               return;
                           }
   
     return(0);                          (*s_etat_processus).erreur_systeme = d_es_processus;
 }                          return;
                       }
                   }
               }
   
 int              pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux));
 envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,          }
         enum signaux_rpl signal)  
 {  
     (*s_etat_processus_a_signaler).signaux_en_queue  
             [(*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1] =  
             signal;  
   
     // On valide l'écriture. Cela évite l'utilisation d'un mutex.          pthread_mutex_unlock(&mutex_liste_threads);
       }
   
     (*s_etat_processus_a_signaler).pointeur_signal_ecriture++;      return;
     return(0);  
 }  }
   
   
Line 2566  nom_segment(unsigned char *chemin, pid_t Line 2698  nom_segment(unsigned char *chemin, pid_t
 #   ifdef IPCS_SYSV // !POSIX  #   ifdef IPCS_SYSV // !POSIX
 #       ifndef OS2 // !OS2  #       ifndef OS2 // !OS2
   
             if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *              if ((fichier = sys_malloc((strlen(chemin) + 1 + 256 + 1) *
                     sizeof(unsigned char))) == NULL)                      sizeof(unsigned char))) == NULL)
             {              {
                 return(NULL);                  return(NULL);
Line 2574  nom_segment(unsigned char *chemin, pid_t Line 2706  nom_segment(unsigned char *chemin, pid_t
   
             sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);              sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
 #       else // OS2  #       else // OS2
             if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char)))              if ((fichier = sys_malloc((10 + 256 + 1) * sizeof(unsigned char)))
                     == NULL)                      == NULL)
             {              {
                 return(NULL);                  return(NULL);
Line 2584  nom_segment(unsigned char *chemin, pid_t Line 2716  nom_segment(unsigned char *chemin, pid_t
 #       endif // OS2  #       endif // OS2
 #   else // POSIX  #   else // POSIX
   
         if ((fichier = malloc((1 + 256 + 1) *          if ((fichier = sys_malloc((1 + 256 + 1) *
                 sizeof(unsigned char))) == NULL)                  sizeof(unsigned char))) == NULL)
         {          {
             return(NULL);              return(NULL);
Line 2599  nom_segment(unsigned char *chemin, pid_t Line 2731  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,
           logical1 test_ouverture)
 {  {
     int                             segment;  #   ifndef OS2
           int                         segment;
   #   endif
   
   #   ifndef IPCS_SYSV
           sem_t                       *semaphore;
           sem_t                       *signalisation;
   #   else
           sem_t                       *semaphore;
           sem_t                       *signalisation;
   #       ifndef OS2
               int                     desc;
               key_t                   clef;
   #       endif
   #   endif
   
       struct_queue_signaux            *queue;
   
     pthread_mutexattr_t             attributs_mutex;      struct timespec                 attente;
   
     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)          while(sem_wait(semaphore_queue_signaux) != 0)
     {          {
         free(nom);              if (errno != EINTR)
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              {
         return;                  return(1);
     }              }
           }
   
           (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
                   .pid = pid;
           (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
                   .signal = signal;
   
     s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),          (*s_queue_signaux).pointeur_ecriture =
             PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0);                  ((*s_queue_signaux).pointeur_ecriture + 1)
     close(segment);                  % LONGUEUR_QUEUE_SIGNAUX;
   
     if (((void *) s_queue_signaux) == ((void *) -1))  #       ifndef IPCS_SYSV
           if (msync(s_queue_signaux, sizeof(s_queue_signaux),
                   MS_ASYNC | MS_INVALIDATE) != 0)
           {
               sem_post(semaphore_queue_signaux);
               return(1);
           }
   #       endif
   
           if (sem_post(semaphore_queue_signaux) != 0)
           {
               return(1);
           }
   
           if (sem_post(semaphore_signalisation) != 0)
           {
               return(1);
           }
       }
       else
     {      {
         if (shm_unlink(nom) == -1)          // Le signal est envoyé depuis un processus distinct.
   
   #       ifdef IPCS_SYSV
               if ((nom = nom_segment(racine_segment, pid)) == NULL)
               {
                   return(1);
               }
   
   #           ifndef OS2 // SysV
                   if (test_ouverture == d_vrai)
                   {
                       attente.tv_sec = 0;
                       attente.tv_nsec = GRANULARITE_us * 1000;
   
                       while((desc = open(nom, O_RDWR)) == -1)
                       {
                           nanosleep(&attente, NULL);
                           INCR_GRANULARITE(attente.tv_nsec);
                       }
                   }
                   else
                   {
                       if ((desc = open(nom, O_RDWR)) == -1)
                       {
                           sys_free(nom);
                           return(1);
                       }
                   }
   
                   close(desc);
   
                   if ((clef = ftok(nom, 1)) == -1)
                   {
                       sys_free(nom);
                       return(1);
                   }
   
                   sys_free(nom);
   
                   if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0))
                           == -1)
                   {
                       return(1);
                   }
   
                   queue = shmat(segment, NULL, 0);
   #           else // OS/2
                   if (test_ouverture == d_vrai)
                   {
                       attente.tv_sec = 0;
                       attente.tv_nsec = GRANULARITE_us * 1000;
   
                       while(DosGetNamedSharedMem((PVOID) &queue, nom,
                               PAG_WRITE | PAG_READ) != 0)
                       {
                           nanosleep(&attente, NULL);
                           INCR_GRANULARITE(attente.tv_nsec);
                       }
                   }
                   else
                   {
                       if (DosGetNamedSharedMem((PVOID) &queue, nom,
                               PAG_WRITE | PAG_READ) != 0)
                       {
                           sys_free(nom);
                           return(1);
                       }
                   }
   
                   sys_free(nom);
   #           endif
   #       else // POSIX
               if ((nom = nom_segment(racine_segment, pid)) == NULL)
               {
                   return(1);
               }
   
               if (test_ouverture == d_vrai)
               {
                   attente.tv_sec = 0;
                   attente.tv_nsec = GRANULARITE_us * 1000;
   
                   while((segment = shm_open(nom, O_RDWR, 0)) == -1)
                   {
                       nanosleep(&attente, NULL);
                       INCR_GRANULARITE(attente.tv_nsec);
                   }
               }
               else
               {
                   if ((segment = shm_open(nom, O_RDWR, 0)) == -1)
                   {
                       sys_free(nom);
                       return(1);
                   }
               }
   
               sys_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.
   
           if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)
         {          {
             free(nom);  #           ifndef IPCS_SYSV // POSIX
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;                  if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
             return;                  {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       return(1);
                   }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
               return(1);
         }          }
   
         free(nom);          if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;                  == SEM_FAILED)
         return;          {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                   {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       sem_close(semaphore);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       sem_close(semaphore);
                       return(1);
                   }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           sem_close(semaphore);
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
   
               sem_close(semaphore);
               return(1);
           }
   
           while(sem_wait(semaphore) != 0)
           {
               if (errno != EINTR)
               {
   #               ifndef IPCS_SYSV // POSIX
                       if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE)
                               != 0)
                       {
                           munmap(queue, sizeof(struct_queue_signaux));
                           sem_close(semaphore);
                           sem_close(signalisation);
                           close(segment);
                           return(1);
                       }
   
                       if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                       {
                           sem_close(semaphore);
                           sem_close(signalisation);
                           close(segment);
                           return(1);
                       }
   
                       close(segment);
   #               else // IPCS_SYSV
   #                   ifndef OS2 // SysV
                           if (shmdt(queue) != 0)
                           {
                               sem_close(semaphore);
                               sem_close(signalisation);
                               return(1);
                           }
   #                   else // OS/2
                           // Pendant de DosGetNamedSHaredMem()
   #                   endif
   #               endif
   
                   sem_close(semaphore);
                   sem_close(signalisation);
                   return(1);
               }
           }
   
           (*queue).queue[(*queue).pointeur_ecriture].pid = getpid();
           (*queue).queue[(*queue).pointeur_ecriture].signal = signal;
   
           (*queue).pointeur_ecriture = ((*queue).pointeur_ecriture + 1)
                   % LONGUEUR_QUEUE_SIGNAUX;
   
           if (sem_post(semaphore) != 0)
           {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                   {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       sem_close(semaphore);
                       sem_close(signalisation);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       sem_close(semaphore);
                       sem_close(signalisation);
                       return(1);
                   }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           sem_close(semaphore);
                           sem_close(signalisation);
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
   
               sem_close(semaphore);
               sem_close(signalisation);
               return(1);
           }
   
           if (sem_close(semaphore) != 0)
           {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                   {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       sem_close(signalisation);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       sem_close(signalisation);
                       return(1);
                   }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           sem_close(signalisation);
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
   
               sem_close(signalisation);
               return(1);
           }
   
           if (sem_post(signalisation) != 0)
           {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                   {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       sem_close(signalisation);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       sem_close(signalisation);
                       return(1);
                   }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           sem_close(signalisation);
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
   
               sem_close(signalisation);
               return(1);
           }
   
           if (sem_close(signalisation) != 0)
           {
   #           ifndef IPCS_SYSV // POSIX
                   if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                   {
                       munmap(queue, sizeof(struct_queue_signaux));
                       close(segment);
                       return(1);
                   }
   
                   if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
                   {
                       close(segment);
                       return(1);
                   }
   
                   close(segment);
   #           else // IPCS_SYSV
   #               ifndef OS2 // SysV
                       if (shmdt(queue) != 0)
                       {
                           return(1);
                       }
   #               else // OS/2
                       // Pendant de DosGetNamedSHaredMem()
   #               endif
   #           endif
   
               return(1);
           }
   
   #       ifndef IPCS_SYSV // POSIX
               if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
               {
                   munmap(queue, sizeof(struct_queue_signaux));
                   close(segment);
                   return(1);
               }
   
               if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
               {
                   close(segment);
                   return(1);
               }
   
               close(segment);
   #       else // IPCS_SYSV
   #           ifndef OS2 // SysV
                   if (shmdt(queue) != 0)
                   {
                       return(1);
                   }
   #           else // OS/2
                   // Pendant de DosGetNamedSHaredMem()
   #           endif
   #       endif
     }      }
   
     free(nom);      return(0);
   }
   
     pthread_mutexattr_init(&attributs_mutex);  int
     pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL);  envoi_signal_thread(struct_processus *s_contexte,
     pthread_mutex_init(&((*s_queue_signaux).mutex), &attributs_mutex);          pthread_t tid, enum signaux_rpl signal)
     pthread_mutexattr_destroy(&attributs_mutex);  {
       // Un signal est envoyé d'un thread à un autre thread du même processus.
   
     (*s_queue_signaux).pointeur_lecture = 0;      int                                     ios;
     (*s_queue_signaux).pointeur_ecriture = 0;  
   
 #   else // SystemV      struct timespec                         attente;
 #   ifndef OS2  
   
     file                            *desc;      volatile struct_liste_chainee_volatile  *l_element_courant;
   
     key_t                           clef;      struct_processus                        *s_etat_processus;
   
     // Création d'un segment de données associé au PID du processus courant      if (s_contexte != NULL)
       {
           attente.tv_sec = 0;
           attente.tv_nsec = GRANULARITE_us * 1000;
   
     chemin = (*s_etat_processus).chemin_fichiers_temporaires;          while((ios = pthread_mutex_trylock(&mutex_liste_threads)) != 0)
           {
               if (ios != EBUSY)
               {
                   return(1);
               }
   
     if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,              if (sem_post(&((*s_contexte).semaphore_fork)) != 0)
             getpid())) == NULL)              {
                   return(1);
               }
   
               nanosleep(&attente, NULL);
               INCR_GRANULARITE(attente.tv_nsec);
   
               while(sem_wait(&((*s_contexte).semaphore_fork)) != 0)
               {
                   if (errno != EINTR)
                   {
                       return(1);
                   }
               }
           }
       }
       else
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          if (pthread_mutex_lock(&mutex_liste_threads) != 0)
         return;          {
               return(1);
           }
     }      }
   
     if ((desc = fopen(nom, "w")) == NULL)      l_element_courant = liste_threads;
   
       while(l_element_courant != NULL)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;          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;
       }
   
       if (l_element_courant == NULL)
       {
           pthread_mutex_unlock(&mutex_liste_threads);
           return(1);
     }      }
   
     fclose(desc);      s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
               .s_etat_processus;
   
     if ((clef = ftok(nom, 1)) == -1)      if (pthread_mutex_lock(&((*s_etat_processus).mutex_signaux)) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          pthread_mutex_unlock(&mutex_liste_threads);
         return;          return(1);
     }      }
   
     free(nom);      (*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 ((segment = shmget(clef,      if (pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux)) != 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);
       }
   
       if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
       {
           return(1);
     }      }
   
     fifos = shmat(segment, NULL, 0);      if (sem_post(semaphore_signalisation) != 0)
       {
           return(1);
       }
   
     if (((void *) fifos) == ((void *) -1))      return(0);
   }
   
   int
   envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
           enum signaux_rpl signal)
   {
       pthread_mutex_lock(&((*s_etat_processus_a_signaler).mutex_signaux));
       (*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_kill((*s_etat_processus_a_signaler).tid, SIGUSR2);
       pthread_mutex_unlock(&((*s_etat_processus_a_signaler).mutex_signaux));
   
       if (sem_post(semaphore_signalisation) != 0)
     {      {
         if (shmctl(segment, IPC_RMID, 0) == -1)          return(1);
       }
   
       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)
   {
       pthread_attr_t                  attributs;
   
       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,
                   S_IRUSR | S_IWUSR)) == -1)
           {
               if (errno != EEXIST)
               {
                   sys_free(nom);
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               if ((*s_etat_processus).langue == 'F')
               {
                   printf("+++Attention : Le segment de mémoire %s préexiste !\n",
                           nom);
               }
               else
               {
                   printf("+++Warning: %s memory segment preexists!\n", nom);
               }
   
               if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_TRUNC,
                       S_IRUSR | S_IWUSR)) == -1)
               {
                   sys_free(nom);
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
           }
   
           if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)
           {
               sys_free(nom);
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),
                   PROT_READ | PROT_WRITE, MAP_SHARED, f_queue_signaux, 0);
   
           if (((void *) s_queue_signaux) == ((void *) -1))
           {
               if (shm_unlink(nom) == -1)
               {
                   sys_free(nom);
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               sys_free(nom);
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           sys_free(nom);
   
           if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
                   == SEM_FAILED)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           if ((semaphore_signalisation = sem_init2(0, getpid(),
                   SEM_SIGNALISATION)) == SEM_FAILED)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           if ((semaphore_arret_signalisation = sem_init2(1, getpid(),
                   SEM_ARRET_SIGNALISATION)) == SEM_FAILED)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           (*s_queue_signaux).pointeur_lecture = 0;
           (*s_queue_signaux).pointeur_ecriture = 0;
   
           (*s_queue_signaux).requete_arret = d_faux;
   
           if (msync(s_queue_signaux, sizeof(struct_queue_signaux),
                   MS_ASYNC | MS_INVALIDATE) != 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);
               sys_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;
               }
   
               if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
                       == SEM_FAILED)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               if ((semaphore_signalisation = sem_init2(0, getpid(),
                       SEM_SIGNALISATION)) == SEM_FAILED)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               if ((semaphore_arret_signalisation = sem_init2(1, getpid(),
                       SEM_ARRET_SIGNALISATION)) == SEM_FAILED)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               (*s_queue_signaux).pointeur_lecture = 0;
               (*s_queue_signaux).pointeur_ecriture = 0;
               (*s_queue_signaux).requete_arret = d_faux;
   #       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)
               {
                   sys_free(nom);
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               sys_free(nom);
   
               if (sem_init(&((*s_queue_signaux).semaphore), 1, 1) != 0)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               if (sem_init(&((*s_queue_signaux).signalisation), 1, 0) != 0)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               if (sem_init(&((*s_queue_signaux).arret_signalisation), 1, 1) != 0)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               (*s_queue_signaux).pointeur_lecture = 0;
               (*s_queue_signaux).pointeur_ecriture = 0;
               (*s_queue_signaux).requete_arret = d_faux;
   #       endif
   #   endif
   
       (*s_queue_signaux).controle = getpid();
   
       if (lancement_thread_signaux(s_etat_processus) == d_erreur)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
   
 #   else      // Lancement du thread de récupération des signaux.
   
     if ((nom = nom_segment(NULL, getpid())) == NULL)      if (pthread_attr_init(&attributs) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
   
     if (DosAllocSharedMem(&ptr_os2, nom, nombre_queues *      if (pthread_attr_setdetachstate(&attributs,
             ((2 * longueur_queue) + 4) * sizeof(int),              PTHREAD_CREATE_JOINABLE) != 0)
             PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)  
     {      {
         free(nom);          (*s_etat_processus).erreur_systeme = d_es_processus;
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;  
         return;          return;
     }      }
   
     free(nom);      if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs,
     fifos = ptr_os2;              thread_surveillance_signaux, s_etat_processus) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
 #   endif      if (pthread_attr_destroy(&attributs) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
   #   ifndef IPCS_SYSV
       if (msync(s_queue_signaux, sizeof(s_queue_signaux),
               MS_ASYNC | MS_INVALIDATE) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
 #   endif  #   endif
   
     return;      return;
Line 2772  liberation_queue_signaux(struct_processu Line 3647  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
           sem_close(semaphore_queue_signaux);
           sem_close(semaphore_signalisation);
           sem_close(semaphore_arret_signalisation);
   
         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 3688  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;  
   
 #   ifdef IPCS_SYSV // SystemV  
 #   ifndef OS2  #   ifndef OS2
           unsigned char       *nom;
   #   endif
   
       // On dépile les interruptions pour arrêter les SIGUSR2 sur
       // le processus courant.
   
       scrutation_interruptions(s_etat_processus);
   
     if (shmdt(fifos) == -1)      while(sem_wait(semaphore_arret_signalisation) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          if (errno != EINTR)
         return;          {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
     }      }
   
     if (shmctl(segment, IPC_RMID, 0) == -1)      (*s_queue_signaux).requete_arret = d_vrai;
   
   #   ifndef IPCS_SYSV
       msync(s_queue_signaux, sizeof(s_queue_signaux), MS_ASYNC | MS_INVALIDATE);
   #   endif
   
       sem_post(semaphore_arret_signalisation);
   
       // Incrémenter le sémaphore pour être sûr de le débloquer.
   
       sem_post(semaphore_signalisation);
   
       if ((*s_queue_signaux).controle == getpid())
     {      {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;          pthread_join((*s_queue_signaux).thread_signaux, NULL);
         return;  
     }      }
       else
     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_processus;
         return;          return;
     }      }
   
     unlink(nom);      arret_thread_signaux(s_etat_processus);
     free(nom);  
   
 #   else  #   ifdef IPCS_SYSV // SystemV
   #       ifndef OS2
               // Il faut commencer par éliminer le sémaphore.
   
     if (DosFreeMem(fifos) != 0)              if (semctl((*semaphore_queue_signaux).sem, 0, IPC_RMID) == -1)
     {              {
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;                  (*s_etat_processus).erreur_systeme = d_es_processus;
         return;                  return;
     }              }
   
 #   endif              unlink((*semaphore_queue_signaux).path);
               sys_free((*semaphore_queue_signaux).path);
   
               if (semctl((*semaphore_signalisation).sem, 0, IPC_RMID) == -1)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               unlink((*semaphore_signalisation).path);
               sys_free((*semaphore_signalisation).path);
   
               if (semctl((*semaphore_arret_signalisation).sem, 0, IPC_RMID) == -1)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               unlink((*semaphore_arret_signalisation).path);
               sys_free((*semaphore_arret_signalisation).path);
   
               if (shmdt(s_queue_signaux) == -1)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               if ((nom = nom_segment((*s_etat_processus)
                       .chemin_fichiers_temporaires, getpid())) == NULL)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   
               unlink(nom);
               sys_free(nom);
   #       else
               sem_close(&((*s_queue_signaux).semaphore));
               sem_destroy(&((*s_queue_signaux).semaphore));
   
               sem_close(&((*s_queue_signaux).signalisation));
               sem_destroy(&((*s_queue_signaux).signalisation));
   
               sem_close(&((*s_queue_signaux).arret_signalisation));
               sem_destroy(&((*s_queue_signaux).arret_signalisation));
   
               if (DosFreeMem(s_queue_signaux) != 0)
               {
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return;
               }
   #       endif
 #   else // POSIX  #   else // POSIX
           sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);
           sem_destroy2(semaphore_signalisation, getpid(), SEM_SIGNALISATION);
           sem_destroy2(semaphore_arret_signalisation, getpid(),
                   SEM_ARRET_SIGNALISATION);
   
     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)
           {
               sys_free(nom);
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return;
           }
   
           sys_free(nom);
 #   endif  #   endif
   
     return;      return;

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


CVSweb interface <joel.bertrand@systella.fr>