Diff for /rpl/src/interruptions.c between versions 1.77 and 1.157

version 1.77, 2011/09/20 08:56:24 version 1.157, 2015/02/19 11:01:28
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.3    RPL/2 (R) version 4.1.21
   Copyright (C) 1989-2011 Dr. BERTRAND Joël    Copyright (C) 1989-2015 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
   
Line 52  typedef struct liste_chainee_volatile Line 52  typedef struct liste_chainee_volatile
     volatile void                           *donnee;      volatile void                           *donnee;
 } struct_liste_chainee_volatile;  } struct_liste_chainee_volatile;
   
   
 static volatile struct_liste_chainee_volatile   *liste_threads  static volatile struct_liste_chainee_volatile   *liste_threads
         = NULL;          = NULL;
 static volatile struct_liste_chainee_volatile   *liste_threads_surveillance  static volatile struct_liste_chainee_volatile   *liste_threads_surveillance
Line 61  static volatile int        code_erreur_g Line 60  static volatile int        code_erreur_g
   
 unsigned char                                   *racine_segment;  unsigned char                                   *racine_segment;
   
 static pthread_mutex_t                          mutex_interruptions  static void *
         = PTHREAD_MUTEX_INITIALIZER;  thread_surveillance_signaux(void *argument)
   {
       // Cette fonction est lancée dans un thread créé par processus pour
       // gérer le cas des appels système qui seraient bloqués lors de l'arrivée du
       // signal SIGALRM. Les processus externes n'envoient plus un signal au
       // processus ou au thread à signaler mais positionnent les informations
       // nécessaires dans la queue des signaux et incrémentent le sémaphore.
       // Le sémaphore est décrémenté lorsque le signal est effectivement traité.
   
       int                                     nombre_signaux_envoyes;
   
       struct_processus                        *s_etat_processus;
   
       struct timespec                         attente;
   
       volatile struct_liste_chainee_volatile  *l_element_courant;
   
       sigset_t                                set;
   
       sigfillset(&set);
       pthread_sigmask(SIG_BLOCK, &set, NULL);
   
       s_etat_processus = (struct_processus *) argument;
   
       for(;;)
       {
           attente.tv_sec = 0;
           attente.tv_nsec = GRANULARITE_us * 1000;
   
           if (sem_wait(semaphore_signalisation) == 0)
           {
               if (sem_wait(semaphore_arret_signalisation) != 0)
               {
                   (*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_arret_signalisation);
               sem_post(semaphore_signalisation);
   
               nombre_signaux_envoyes = 0;
               sched_yield();
   
               // Dans un premier temps, on verrouille la queue des signaux
               // affectée au processus courant pour vérifier s'il y a quelque
               // chose à traiter.
   
               sem_wait(semaphore_queue_signaux);
   
               if ((*s_queue_signaux).pointeur_lecture !=
                       (*s_queue_signaux).pointeur_ecriture)
               {
                   // Attention : raise() envoit le signal au thread appelant !
                   // kill() l'envoie au processus appelant, donc dans notre
                   // cas à un thread aléatoire du processus, ce qui nous
                   // convient tout à fait puisqu'il s'agit de débloquer les
                   // appels système lents.
   
                   nombre_signaux_envoyes++;
                   kill(getpid(), SIGALRM);
               }
   
               sem_post(semaphore_queue_signaux);
   
               // Dans un second temps, on balaye toutes les queues de signaux
               // des threads du processus courant.
   
               // Attention : l'ordre de verrouillage des mutexes est important
               // pour éviter les conditions bloquantes !
   
               pthread_mutex_lock(&mutex_liste_threads);
   
               l_element_courant = liste_threads;
   
               while(l_element_courant != NULL)
               {
                   if ((*((struct_thread *) (*l_element_courant).donnee)).pid
                           == getpid())
                   {
                       pthread_mutex_lock(&((*(*((struct_thread *)
                               (*l_element_courant).donnee)).s_etat_processus)
                               .mutex_signaux));
   
                       if ((*(*((struct_thread *) (*l_element_courant).donnee))
                               .s_etat_processus).pointeur_signal_ecriture !=
                               (*(*((struct_thread *) (*l_element_courant)
                               .donnee)).s_etat_processus)
                               .pointeur_signal_lecture)
                       {
                           nombre_signaux_envoyes++;
                           pthread_kill((*((struct_thread *)
                                   (*l_element_courant).donnee)).tid, SIGALRM);
                       }
   
                       pthread_mutex_unlock(&((*(*((struct_thread *)
                               (*l_element_courant).donnee)).s_etat_processus)
                               .mutex_signaux));
                   }
   
                   l_element_courant = (*l_element_courant).suivant;
               }
   
               pthread_mutex_unlock(&mutex_liste_threads);
   
               // Nanosleep
   
               if (nombre_signaux_envoyes > 0)
               {
                   nanosleep(&attente, NULL);
               }
           }
           else
           {
               if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
               }
           }
       }
   
       pthread_exit(NULL);
   }
   
 void  void
 modification_pid_thread_pere(struct_processus *s_etat_processus)  modification_pid_thread_pere(struct_processus *s_etat_processus)
Line 207  retrait_thread(struct_processus *s_etat_ Line 334  retrait_thread(struct_processus *s_etat_
         return;          return;
     }      }
   
       // Le thread ne peut plus traiter de signaux explicites. Il convient
       // alors de corriger le sémaphore pour annuler les signaux en attente.
   
       while((*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus)
               .pointeur_signal_ecriture != (*(*((struct_thread *)
               (*l_element_courant).donnee)).s_etat_processus)
               .pointeur_signal_lecture)
       {
           while(sem_wait(semaphore_signalisation) != 0)
           {
               if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
           }
   
           (*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus)
                   .pointeur_signal_lecture = ((*(*((struct_thread *)
                   (*l_element_courant).donnee)).s_etat_processus)
                   .pointeur_signal_lecture + 1) % LONGUEUR_QUEUE_SIGNAUX;
       }
   
     free((void *) (*l_element_courant).donnee);      free((void *) (*l_element_courant).donnee);
     free((struct_liste_chainee_volatile *) l_element_courant);      free((struct_liste_chainee_volatile *) l_element_courant);
   
Line 324  verrouillage_threads_concurrents(struct_ Line 474  verrouillage_threads_concurrents(struct_
                 == getpid()) && (pthread_equal((*((struct_thread *)                  == getpid()) && (pthread_equal((*((struct_thread *)
                 (*l_element_courant).donnee)).tid, pthread_self()) == 0))                  (*l_element_courant).donnee)).tid, pthread_self()) == 0))
         {          {
             if (sem_wait(&((*(*((struct_thread *) (*l_element_courant)  #           ifndef SEMAPHORES_NOMMES
                     .donnee)).s_etat_processus).semaphore_fork)) == -1)                  while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)
                           .donnee)).s_etat_processus).semaphore_fork)) == -1)
   #           else
                   while(sem_wait((*(*((struct_thread *) (*l_element_courant)
                           .donnee)).s_etat_processus).semaphore_fork) == -1)
   #           endif
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                 return;                  return;
Line 351  deverrouillage_threads_concurrents(struc Line 506  deverrouillage_threads_concurrents(struc
                 == getpid()) && (pthread_equal((*((struct_thread *)                  == getpid()) && (pthread_equal((*((struct_thread *)
                 (*l_element_courant).donnee)).tid, pthread_self()) == 0))                  (*l_element_courant).donnee)).tid, pthread_self()) == 0))
         {          {
             if (sem_post(&((*(*((struct_thread *)  #           ifndef SEMAPHORES_NOMMES
                     (*l_element_courant).donnee)).s_etat_processus)                  if (sem_post(&((*(*((struct_thread *)
                     .semaphore_fork)) != 0)                          (*l_element_courant).donnee)).s_etat_processus)
                           .semaphore_fork)) != 0)
   #           else
                   if (sem_post((*(*((struct_thread *)
                           (*l_element_courant).donnee)).s_etat_processus)
                           .semaphore_fork) != 0)
   #           endif
             {              {
                 if (pthread_mutex_unlock(&mutex_liste_threads) != 0)                  if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
                 {                  {
Line 387  liberation_threads(struct_processus *s_e Line 548  liberation_threads(struct_processus *s_e
   
     struct_processus                            *candidat;      struct_processus                            *candidat;
   
     unsigned long                               i;      struct_liste_variables_partagees            *l_element_partage_courant;
       struct_liste_variables_partagees            *l_element_partage_suivant;
   
       struct_liste_variables_statiques            *l_element_statique_courant;
       struct_liste_variables_statiques            *l_element_statique_suivant;
   
       integer8                                    i;
   
     void                                        *element_candidat;      void                                        *element_candidat;
     void                                        *element_courant;      void                                        *element_courant;
Line 430  liberation_threads(struct_processus *s_e Line 597  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 499  liberation_threads(struct_processus *s_e Line 665  liberation_threads(struct_processus *s_e
                     close((*s_argument_thread).pipe_acquittement[1]);                      close((*s_argument_thread).pipe_acquittement[1]);
                     close((*s_argument_thread).pipe_injections[1]);                      close((*s_argument_thread).pipe_injections[1]);
                     close((*s_argument_thread).pipe_nombre_injections[1]);                      close((*s_argument_thread).pipe_nombre_injections[1]);
                     close((*s_argument_thread).pipe_nombre_objets_attente[0]);                      close((*s_argument_thread).pipe_nombre_elements_attente[0]);
                     close((*s_argument_thread).pipe_interruptions[0]);                      close((*s_argument_thread).pipe_interruptions[0]);
                     close((*s_argument_thread)  
                             .pipe_nombre_interruptions_attente[0]);  
   
                     if (pthread_mutex_unlock(&((*s_argument_thread)                      if (pthread_mutex_unlock(&((*s_argument_thread)
                             .mutex_nombre_references)) != 0)                              .mutex_nombre_references)) != 0)
Line 602  liberation_threads(struct_processus *s_e Line 766  liberation_threads(struct_processus *s_e
                 }                  }
             }              }
   
             liberation_arbre_variables(s_etat_processus,              // ne peut être effacé qu'une seule fois
                     (*s_etat_processus).s_arbre_variables, d_faux);  
   
             for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)  
             {  
                 pthread_mutex_trylock(&((*(*s_etat_processus)  
                         .s_liste_variables_statiques[i].objet).mutex));  
                 pthread_mutex_unlock(&((*(*s_etat_processus)  
                         .s_liste_variables_statiques[i].objet).mutex));  
   
                 liberation(s_etat_processus, (*s_etat_processus)  
                         .s_liste_variables_statiques[i].objet);  
                 free((*s_etat_processus).s_liste_variables_statiques[i].nom);  
             }  
   
             free((*s_etat_processus).s_liste_variables_statiques);  
   
             // Ne peut être effacé qu'une seule fois  
             if (suppression_variables_partagees == d_faux)              if (suppression_variables_partagees == d_faux)
             {              {
                 suppression_variables_partagees = d_vrai;                  suppression_variables_partagees = d_vrai;
   
                 for(i = 0; i < (*(*s_etat_processus)                  liberation_arbre_variables_partagees(s_etat_processus,
                         .s_liste_variables_partagees).nombre_variables; i++)                          (*(*s_etat_processus).s_arbre_variables_partagees));
                 {  
                     pthread_mutex_trylock(&((*(*(*s_etat_processus)  
                             .s_liste_variables_partagees).table[i].objet)  
                             .mutex));  
                     pthread_mutex_unlock(&((*(*(*s_etat_processus)  
                             .s_liste_variables_partagees).table[i].objet)  
                             .mutex));  
   
                     liberation(s_etat_processus, (*(*s_etat_processus)                  l_element_partage_courant = (*(*s_etat_processus)
                             .s_liste_variables_partagees).table[i].objet);                          .l_liste_variables_partagees);
                     free((*(*s_etat_processus).s_liste_variables_partagees)  
                             .table[i].nom);  
                 }  
   
                 if ((*(*s_etat_processus).s_liste_variables_partagees).table                  while(l_element_partage_courant != NULL)
                         != NULL)  
                 {                  {
                     free((struct_variable_partagee *) (*(*s_etat_processus)                      l_element_partage_suivant =
                             .s_liste_variables_partagees).table);                              (*l_element_partage_courant).suivant;
                       free(l_element_partage_courant);
                       l_element_partage_courant = l_element_partage_suivant;
                 }                  }
               }
   
                 pthread_mutex_trylock(&((*(*s_etat_processus)              liberation_arbre_variables(s_etat_processus,
                         .s_liste_variables_partagees).mutex));                      (*s_etat_processus).s_arbre_variables, d_faux);
                 pthread_mutex_unlock(&((*(*s_etat_processus)  
                         .s_liste_variables_partagees).mutex));              l_element_statique_courant = (*s_etat_processus)
                       .l_liste_variables_statiques;
   
               while(l_element_statique_courant != NULL)
               {
                   l_element_statique_suivant =
                       (*l_element_statique_courant).suivant;
                   free(l_element_statique_courant);
                   l_element_statique_courant = l_element_statique_suivant;
             }              }
   
             element_courant = (*s_etat_processus).l_base_pile;              element_courant = (*s_etat_processus).l_base_pile;
Line 1109  liberation_threads(struct_processus *s_e Line 1256  liberation_threads(struct_processus *s_e
   
             liberation_allocateur(s_etat_processus);              liberation_allocateur(s_etat_processus);
   
             sem_post(&((*s_etat_processus).semaphore_fork));  #           ifndef SEMAPHORES_NOMMES
             sem_destroy(&((*s_etat_processus).semaphore_fork));                  sem_post(&((*s_etat_processus).semaphore_fork));
                   sem_destroy(&((*s_etat_processus).semaphore_fork));
   #           else
                   sem_post((*s_etat_processus).semaphore_fork);
                   sem_close((*s_etat_processus).semaphore_fork);
   #           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 1155  liberation_threads(struct_processus *s_e Line 1308  liberation_threads(struct_processus *s_e
             close((*s_argument_thread).pipe_acquittement[1]);              close((*s_argument_thread).pipe_acquittement[1]);
             close((*s_argument_thread).pipe_injections[1]);              close((*s_argument_thread).pipe_injections[1]);
             close((*s_argument_thread).pipe_nombre_injections[1]);              close((*s_argument_thread).pipe_nombre_injections[1]);
             close((*s_argument_thread).pipe_nombre_objets_attente[0]);              close((*s_argument_thread).pipe_nombre_elements_attente[0]);
             close((*s_argument_thread).pipe_interruptions[0]);              close((*s_argument_thread).pipe_interruptions[0]);
             close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);  
   
             if (pthread_mutex_unlock(&((*s_argument_thread)              if (pthread_mutex_unlock(&((*s_argument_thread)
                     .mutex_nombre_references)) != 0)                      .mutex_nombre_references)) != 0)
Line 1215  recherche_thread(pid_t pid, pthread_t ti Line 1367  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 1235  recherche_thread(pid_t pid, pthread_t ti Line 1392  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 1296  recherche_thread_principal(pid_t pid) Line 1459  recherche_thread_principal(pid_t pid)
 static inline void  static inline void
 verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)  verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
 {  {
     int         semaphore;  
   
     if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)  
     {  
         BUG(1, uprintf("Lock error !\n"));  
         return;  
     }  
   
     // Il faut respecteur l'atomicité des deux opérations suivantes !  
   
     if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) != 0)  
     {  
         sem_wait(&((*s_etat_processus).semaphore_fork));  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }  
   
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
     if (sem_post(&semaphore_gestionnaires_signaux) == -1)      if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
 #   else  #   else
     if (sem_post(semaphore_gestionnaires_signaux) == -1)      if (sem_post((*s_etat_processus).semaphore_fork) != 0)
 #   endif  #   endif
     {      {
         sem_wait(&((*s_etat_processus).semaphore_fork));  
         BUG(1, uprintf("Lock error !\n"));          BUG(1, uprintf("Lock error !\n"));
         return;          return;
     }      }
   
       return;
   }
   
   static inline void
   deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
   {
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)      while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
 #   else  #   else
     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)      while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
 #   endif  #   endif
     {      {
         sem_wait(&((*s_etat_processus).semaphore_fork));          if (errno != EINTR)
         BUG(1, uprintf("Lock error !\n"));  
         return;  
     }  
   
     if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)  
     {  
         sem_wait(&((*s_etat_processus).semaphore_fork));  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }  
   
     if (semaphore == 1)  
     {  
         // Le semaphore ne peut être pris par le thread qui a appelé  
         // le gestionnaire de signal car le signal est bloqué par ce thread  
         // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que  
         // par un thread concurrent. On essaye donc de le bloquer jusqu'à  
         // ce que ce soit possible.  
   
         if (pthread_mutex_lock(&mutex_liste_threads) != 0)  
         {          {
             sem_wait(&((*s_etat_processus).semaphore_fork));              BUG(1, uprintf("Unlock error !\n"));
             BUG(1, uprintf("Lock error !\n"));  
             return;              return;
         }          }
     }      }
Line 1361  verrouillage_gestionnaire_signaux(struct Line 1491  verrouillage_gestionnaire_signaux(struct
     return;      return;
 }  }
   
 static inline void  /*
 deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)  ================================================================================
     Fonctions de gestion des signaux dans les threads.
   
     Lorsqu'un processus reçoit un signal, il appelle le gestionnaire de signal
     associé qui ne fait qu'envoyer au travers de write() le signal
     reçus dans un pipe. Un second thread est bloqué sur ce pipe et
     effectue le traitement adéquat pour le signal donné.
   ================================================================================
   */
   
   #define test_signal(signal) \
       if (signal_test == SIGTEST) { signal_test = signal; return; }
   
   static int          pipe_signaux;
   
   logical1
   lancement_thread_signaux(struct_processus *s_etat_processus)
 {  {
     int         semaphore;      pthread_attr_t                  attributs;
   
     // Il faut respecteur l'atomicité des deux opérations suivantes !      void                            *argument;
   
     if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) == -1)      if (pipe((*s_etat_processus).pipe_signaux) != 0)
     {      {
         sem_wait(&((*s_etat_processus).semaphore_fork));          (*s_etat_processus).erreur_systeme = d_es_processus;
         BUG(1, uprintf("Unlock 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 (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)  
 #   endif  
     {  
         sem_wait(&((*s_etat_processus).semaphore_fork));  
         BUG(1, uprintf("Unlock error !\n"));  
         return;  
     }  
   
 #   ifndef SEMAPHORES_NOMMES      if (pthread_attr_init(&attributs) != 0)
     while(sem_wait(&semaphore_gestionnaires_signaux) == -1)  
 #   else  
     while(sem_wait(semaphore_gestionnaires_signaux) == -1)  
 #   endif  
     {      {
         if (errno != EINTR)          (*s_etat_processus).erreur_systeme = d_es_processus;
         {          return(d_erreur);
             sem_wait(&((*s_etat_processus).semaphore_fork));  
             BUG(1, uprintf("Unlock error !\n"));  
             return;  
         }  
     }      }
   
     if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)      if (pthread_attr_setdetachstate(&attributs, PTHREAD_CREATE_JOINABLE) != 0)
     {      {
         sem_wait(&((*s_etat_processus).semaphore_fork));          (*s_etat_processus).erreur_systeme = d_es_processus;
         BUG(1, uprintf("Unlock error !\n"));          return(d_erreur);
         return;  
     }      }
   
     if (sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)      argument = (*s_etat_processus).pipe_signaux;
   
       if (pthread_create(&((*s_etat_processus).thread_signaux), &attributs,
               thread_signaux, argument) != 0)
     {      {
         BUG(1, uprintf("Unlock error !\n"));          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return(d_erreur);
     }      }
   
     if (semaphore == 1)      return(d_absence_erreur);
   }
   
   logical1
   arret_thread_signaux(struct_processus *s_etat_processus)
   {
       unsigned char       signal;
       ssize_t             n;
   
       signal = (unsigned char ) (rpl_sigmax & 0xFF);
   
       do
     {      {
         if (pthread_mutex_unlock(&mutex_liste_threads) != 0)          n = write((*s_etat_processus).pipe_signaux[1], &signal, sizeof(signal));
   
           if (n < 0)
         {          {
             BUG(1, uprintf("Unlock error !\n"));              return(d_erreur);
             return;  
         }          }
     }      } while(n != 1);
   
     return;      pthread_join((*s_etat_processus).thread_signaux, NULL);
   
       close((*s_etat_processus).pipe_signaux[0]);
       close((*s_etat_processus).pipe_signaux[1]);
   
       return(d_absence_erreur);
 }  }
   
 #define test_signal(signal) \  void *
     if (signal_test == SIGTEST) { signal_test = signal; return; }  thread_signaux(void *argument)
   {
       int                     *pipe;
   
       sigset_t                masque;
   
       struct pollfd           fds;
   
       unsigned char           signal;
   
       pipe = (int *) argument;
       fds.fd = pipe[0];
       fds.events = POLLIN;
       fds.revents = 0;
   
       sigfillset(&masque);
       pthread_sigmask(SIG_BLOCK, &masque, NULL);
   
       do
       {
           if (poll(&fds, 1, -1) == -1)
           {
               pthread_exit(NULL);
           }
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
           read(fds.fd, &signal, 1);
   
   #   pragma GCC diagnostic pop
   
           if (signal != (0xFF & rpl_sigmax))
           {
               envoi_signal_processus(getpid(), signal);
               // Un signal SIGALRM est envoyé par le thread de surveillance
               // des signaux jusqu'à ce que les signaux soient tous traités.
           }
       } while(signal != (0xFF & rpl_sigmax));
   
       pthread_exit(NULL);
   }
   
 // Récupération des signaux  // Récupération des signaux
 // - SIGINT (arrêt au clavier)  // - SIGINT  (arrêt au clavier)
 // - SIGTERM (signal d'arrêt en provenance du système)  // - SIGTERM (signal d'arrêt en provenance du système)
   
 void  void
 interruption1(int signal)  interruption1(int signal)
 {  {
       unsigned char       signal_tronque;
   
     test_signal(signal);      test_signal(signal);
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
     switch(signal)      switch(signal)
     {      {
         case SIGINT:          case SIGINT:
             envoi_signal_processus(getpid(), rpl_sigint);              signal_tronque = (unsigned char) (rpl_sigint & 0xFF);
               write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
             break;              break;
   
         case SIGTERM:          case SIGTERM:
             envoi_signal_processus(getpid(), rpl_sigterm);              signal_tronque = (unsigned char) (rpl_sigterm & 0xFF);
               write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
             break;              break;
   
         case SIGALRM:          case SIGUSR1:
             envoi_signal_processus(getpid(), rpl_sigalrm);              signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);
               write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
               break;
   
           default:
               // SIGALRM
             break;              break;
     }      }
   
   #   pragma GCC diagnostic pop
   
       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);
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
       write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
   
   #   pragma GCC diagnostic pop
   
       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);
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
       write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
   
   #   pragma GCC diagnostic pop
   
       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;      return;
 }  }
   
Line 1508  inline static void Line 1825  inline static void
 signal_term(struct_processus *s_etat_processus, pid_t pid)  signal_term(struct_processus *s_etat_processus, pid_t pid)
 {  {
     struct_processus        *s_thread_principal;      struct_processus        *s_thread_principal;
     volatile sig_atomic_t   exclusion = 0;      pthread_mutex_t         exclusion = PTHREAD_MUTEX_INITIALIZER;
   
     verrouillage_gestionnaire_signaux(s_etat_processus);      verrouillage_gestionnaire_signaux(s_etat_processus);
   
Line 1530  signal_term(struct_processus *s_etat_pro Line 1847  signal_term(struct_processus *s_etat_pro
         {          {
             (*s_etat_processus).var_volatile_traitement_sigint = -1;              (*s_etat_processus).var_volatile_traitement_sigint = -1;
   
             while(exclusion == 1);              pthread_mutex_lock(&exclusion);
             exclusion = 1;  
   
             if ((*s_etat_processus).var_volatile_requete_arret == -1)              if ((*s_etat_processus).var_volatile_requete_arret == -1)
             {              {
                 deverrouillage_gestionnaire_signaux(s_etat_processus);                  deverrouillage_gestionnaire_signaux(s_etat_processus);
                 exclusion = 0;                  pthread_mutex_unlock(&exclusion);
                 return;                  return;
             }              }
   
             (*s_etat_processus).var_volatile_requete_arret = -1;              (*s_etat_processus).var_volatile_requete_arret = -1;
             (*s_etat_processus).var_volatile_alarme = -1;              (*s_etat_processus).var_volatile_alarme = -1;
   
             exclusion = 0;              pthread_mutex_unlock(&exclusion);
         }          }
     }      }
     else      else
Line 1625  signal_int(struct_processus *s_etat_proc Line 1941  signal_int(struct_processus *s_etat_proc
     return;      return;
 }  }
   
 // Récupération des signaux  
 // - SIGFSTP  
 //  
 // ATTENTION :  
 // Le signal SIGFSTP provient de la mort du processus de contrôle.  
 // Sous certains systèmes (Linux...), la mort du terminal de contrôle  
 // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres  
 // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo  
 // non initialisée (pointeur NULL) issue de TERMIO.  
   
 void  
 interruption2(int signal)  
 {  
     test_signal(signal);  
     envoi_signal_processus(getpid(), rpl_sigtstp);  
     return;  
 }  
   
 static inline void  static inline void
 signal_tstp(struct_processus *s_etat_processus, pid_t pid)  signal_tstp(struct_processus *s_etat_processus, pid_t pid)
 {  {
Line 1690  signal_tstp(struct_processus *s_etat_pro Line 1988  signal_tstp(struct_processus *s_etat_pro
     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.  
   
     unsigned char       message[] = "+++System : Uncaught access violation\n"  
                                 "+++System : Aborting !\n";  
   
     test_signal(signal);  
   
     if (pid_processus_pere == getpid())  
     {      {
         kill(pid_processus_pere, SIGALRM);          case 1:
               longjmp(contexte_ecriture, -1);
               break;
   
           case 2:
               longjmp(contexte_impression, -1);
               break;
     }      }
   
     write(STDERR_FILENO, message, strlen(message));      return;
     _exit(EXIT_FAILURE);  
 }  }
   
 #if 0  void
 // Utiliser libsigsegv  interruption_depassement_pile(int urgence, stackoverflow_context_t scp)
 void INTERRUPTION3_A_FIXER()  
 {  {
     pthread_t               thread;      if ((urgence == 0) && (routine_recursive != 0))
   
     struct_processus        *s_etat_processus;  
   
     test_signal(signal);  
     verrouillage_gestionnaire_signaux(s_etat_processus);  
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)  
     {      {
         deverrouillage_gestionnaire_signaux(s_etat_processus);          // On peut tenter de récupérer le dépassement de pile. Si la variable
         return;          // 'routine_recursive' est non nulle, on récupère l'erreur.
     }  
   
     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)  
     {  
         printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),  
                 (unsigned long long) pthread_self());  
         fflush(stdout);  
     }  
   
     if ((*s_etat_processus).var_volatile_recursivite == -1)          sigsegv_leave_handler(sortie_interruption_depassement_pile,
     {                  (void *) &routine_recursive, NULL, NULL);
         // Segfault dans un appel de fonction récursive  
         deverrouillage_gestionnaire_signaux(s_etat_processus);  
         longjmp(contexte, -1);  
     }      }
     else  
     {  
         // Segfault dans une routine interne  
         if (strncmp(getenv("LANG"), "fr", 2) == 0)  
         {  
             printf("+++Système : Violation d'accès\n");  
         }  
         else  
         {  
             printf("+++System : Access violation\n");  
         }  
   
         fflush(stdout);  
   
         (*s_etat_processus).compteur_violation_d_acces++;      // Ici, la panique est totale et il vaut mieux quitter l'application.
       interruption3(SIGUSR2);
       return;
   }
   
         if ((*s_etat_processus).compteur_violation_d_acces > 1)  int
         {  interruption_violation_access(void *adresse_fautive, int gravite)
             // 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      unsigned char       message[] = "+++System : Trying to catch access "
             // récupérable et on sort autoritairement du programme. Il peut                                  "violation\n";
             // rester des processus orphelins en attente !  
   
             if (strncmp(getenv("LANG"), "fr", 2) == 0)      static int          compteur_erreur = 0;
             {  
                 printf("+++Système : Violation d'accès, tentative de "  
                         "terminaison de la tâche\n");  
                 printf("             (defauts multiples)\n");  
             }  
             else  
             {  
                 printf("+++System : Access violation, trying to kill task "  
                         "(multiple defaults)\n");  
             }  
   
             fflush(stdout);      if ((gravite == 0) && (routine_recursive != 0))
       {
           // Il peut s'agir d'un dépassement de pile.
   
             deverrouillage_gestionnaire_signaux(s_etat_processus);          sigsegv_leave_handler(sortie_interruption_depassement_pile,
             exit(EXIT_FAILURE);                  (void *) &routine_recursive, NULL, NULL);
         }      }
         else  
         {  
             // Première erreur de segmentation. On essaie de terminer  
             // proprement le thread ou le processus. Le signal ne peut être  
             // envoyé que depuis le même processus.  
   
             if (recherche_thread_principal(getpid(), &thread) == d_vrai)      // On est dans une bonne vieille violation d'accès. On essaie
             {      // de fermer au mieux l'application.
                 if (pthread_equal(thread, pthread_self()) != 0)  
                 {  
                     deverrouillage_gestionnaire_signaux(s_etat_processus);  
   
                     if ((*s_etat_processus).pid_processus_pere != getpid())      compteur_erreur++;
                     {  
                         // On est dans le thread principal d'un processus.  
   
                         longjmp(contexte_processus, -1);      if (compteur_erreur >= 2)
                     }      {
                     else          // Erreurs multiples, on arrête l'application.
                     {          interruption3(SIGSEGV);
                         // On est dans le thread principal du processus          return(0);
                         // père.      }
   
                         longjmp(contexte_initial, -1);  #   pragma GCC diagnostic push
                     }  #   pragma GCC diagnostic ignored "-Wunused-result"
                 }  
                 else  
                 {  
                     // On est dans un thread fils d'un thread principal.  
   
                     deverrouillage_gestionnaire_signaux(s_etat_processus);      write(STDERR_FILENO, message, strlen(message));
                     longjmp(contexte_thread, -1);  
                 }  
             }  
   
             // Là, on ramasse les miettes puisque le thread n'existe plus  #   pragma GCC diagnostic pop
             // dans la base (corruption de la mémoire).  
   
             deverrouillage_gestionnaire_signaux(s_etat_processus);      if (pid_processus_pere == getpid())
             longjmp(contexte_initial, -1);      {
         }          longjmp(contexte_initial, -1);
           return(1);
       }
       else
       {
           longjmp(contexte_processus, -1);
           return(1);
     }      }
   
     deverrouillage_gestionnaire_signaux(s_etat_processus);      // On renvoie 0 parce qu'on décline toute responsabilité quant à la
     return;      // suite des événements...
       return(0);
 }  }
 #endif  
   
 // Traitement de rpl_sigstart  // Traitement de rpl_sigstart
   
Line 1896  signal_stop(struct_processus *s_etat_pro Line 2140  signal_stop(struct_processus *s_etat_pro
   
     if (pid == getpid())      if (pid == getpid())
     {      {
         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))  
                 == NULL)  
         {  
             deverrouillage_gestionnaire_signaux(s_etat_processus);  
             return;  
         }  
   
         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)          if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
         {          {
             printf("[%d] RPL/SIGSTOP (thread %llu)\n", (int) getpid(),              printf("[%d] RPL/SIGSTOP (thread %llu)\n", (int) getpid(),
Line 1965  signal_inject(struct_processus *s_etat_p Line 2202  signal_inject(struct_processus *s_etat_p
     return;      return;
 }  }
   
 // Récupération des signaux  
 // - SIGPIPE  
   
 void  
 interruption5(int signal)  
 {  
     unsigned char       message[] = "+++System : SIGPIPE\n"  
                                 "+++System : Aborting !\n";  
   
     test_signal(signal);  
   
     if (pid_processus_pere == getpid())  
     {  
         envoi_signal_processus(pid_processus_pere, rpl_sigalrm);  
     }  
   
     write(STDERR_FILENO, message, strlen(message));  
     return;  
 }  
   
 static inline void  static inline void
 signal_urg(struct_processus *s_etat_processus, pid_t pid)  signal_urg(struct_processus *s_etat_processus, pid_t pid)
Line 1994  signal_urg(struct_processus *s_etat_proc Line 2212  signal_urg(struct_processus *s_etat_proc
   
     if (pid == getpid())      if (pid == getpid())
     {      {
         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))  
                 == NULL)  
         {  
             deverrouillage_gestionnaire_signaux(s_etat_processus);  
             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 2050  signal_abort(struct_processus *s_etat_pr Line 2261  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(s_etat_processus);  
             return;  
         }  
   
         (*s_etat_processus).arret_depuis_abort = -1;          (*s_etat_processus).arret_depuis_abort = -1;
   
         /*          /*
Line 2092  signal_abort(struct_processus *s_etat_pr Line 2296  signal_abort(struct_processus *s_etat_pr
     return;      return;
 }  }
   
 // Récupération des signaux  
 // - SIGHUP  
   
 void  
 interruption4(int signal)  
 {  
     test_signal(signal);  
     envoi_signal_processus(getpid(), rpl_sighup);  
     return;  
 }  
   
 static inline void  static inline void
 signal_hup(struct_processus *s_etat_processus, pid_t pid)  signal_hup(struct_processus *s_etat_processus, pid_t pid)
Line 2118  signal_hup(struct_processus *s_etat_proc Line 2312  signal_hup(struct_processus *s_etat_proc
         return;          return;
     }      }
   
     snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),      snprintf(nom, 8 + 64 + 1, "rpl-out-%llu-%llu",
             (unsigned long) pthread_self());              (unsigned long long) getpid(),
               (unsigned long long) pthread_self());
   
   #   pragma GCC diagnostic push
   #   pragma GCC diagnostic ignored "-Wunused-result"
   
     if ((fichier = fopen(nom, "w+")) != NULL)      if ((fichier = fopen(nom, "w+")) != NULL)
     {      {
Line 2131  signal_hup(struct_processus *s_etat_proc Line 2329  signal_hup(struct_processus *s_etat_proc
   
     freopen("/dev/null", "r", stdin);      freopen("/dev/null", "r", stdin);
   
   #   pragma GCC diagnostic pop
   
     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)      if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
     {      {
         printf("[%d] RPL/SIGHUP (thread %llu)\n", (int) getpid(),          printf("[%d] RPL/SIGHUP (thread %llu)\n", (int) getpid(),
Line 2228  envoi_interruptions(struct_processus *s_ Line 2428  envoi_interruptions(struct_processus *s_
         default:          default:
             if ((*s_etat_processus).langue == 'F')              if ((*s_etat_processus).langue == 'F')
             {              {
                 printf("+++System : Spurious signal (%d) !\n", signal);                  printf("+++System : Signal inconnu (%d) !\n", signal);
             }              }
             else              else
             {              {
                 printf("+++System : Signal inconnu (%d) !\n", signal);                  printf("+++System : Spurious signal (%d) !\n", signal);
             }              }
   
             break;              break;
Line 2251  scrutation_interruptions(struct_processu Line 2451  scrutation_interruptions(struct_processu
     // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à      // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à
     // écrire.      // écrire.
   
 #   ifndef SEMAPHORES_NOMMES      if (sem_trywait(semaphore_queue_signaux) == 0)
         if (sem_trywait(&((*s_queue_signaux).semaphore)) == 0)  
 #   else  
         if (sem_trywait(semaphore_queue_signaux) == 0)  
 #   endif  
     {      {
         if ((*s_queue_signaux).pointeur_lecture !=          while((*s_queue_signaux).pointeur_lecture !=
                 (*s_queue_signaux).pointeur_ecriture)                  (*s_queue_signaux).pointeur_ecriture)
         {          {
             // Il y a un signal en attente dans le segment partagé. On le              // Il y a un signal en attente dans le segment partagé. On le
Line 2270  scrutation_interruptions(struct_processu Line 2466  scrutation_interruptions(struct_processu
             (*s_queue_signaux).pointeur_lecture =              (*s_queue_signaux).pointeur_lecture =
                     ((*s_queue_signaux).pointeur_lecture + 1)                      ((*s_queue_signaux).pointeur_lecture + 1)
                     % LONGUEUR_QUEUE_SIGNAUX;                      % LONGUEUR_QUEUE_SIGNAUX;
   
   #           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
   
               while(sem_wait(semaphore_signalisation) != 0)
               {
                   if (errno != EINTR)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                       return;
                   }
               }
         }          }
   
 #       ifndef SEMAPHORES_NOMMES          sem_post(semaphore_queue_signaux);
             sem_post(&((*s_queue_signaux).semaphore));  
 #       else  
             sem_post(semaphore_queue_signaux);  
 #       endif  
     }      }
   
     // Interruptions qui arrivent depuis le groupe courant de threads.      // Interruptions qui arrivent depuis le groupe courant de threads.
   
     if (pthread_mutex_trylock(&mutex_interruptions) == 0)      if (pthread_mutex_trylock(&((*s_etat_processus).mutex_signaux)) == 0)
     {      {
         if ((*s_etat_processus).pointeur_signal_lecture !=          while((*s_etat_processus).pointeur_signal_lecture !=
                 (*s_etat_processus).pointeur_signal_ecriture)                  (*s_etat_processus).pointeur_signal_ecriture)
         {          {
             // Il y a un signal dans la queue du thread courant. On le traite.              // Il y a un signal dans la queue du thread courant. On le traite.
Line 2295  scrutation_interruptions(struct_processu Line 2505  scrutation_interruptions(struct_processu
             (*s_etat_processus).pointeur_signal_lecture =              (*s_etat_processus).pointeur_signal_lecture =
                     ((*s_etat_processus).pointeur_signal_lecture + 1)                      ((*s_etat_processus).pointeur_signal_lecture + 1)
                     % LONGUEUR_QUEUE_SIGNAUX;                      % LONGUEUR_QUEUE_SIGNAUX;
   
               while(sem_wait(semaphore_signalisation) != 0)
               {
                   if (errno != EINTR)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                       return;
                   }
               }
         }          }
   
         pthread_mutex_unlock(&mutex_interruptions);          pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux));
     }      }
   
     return;      return;
 }  }
   
   
 /*  /*
 ================================================================================  ================================================================================
   Fonction renvoyant le nom du segment de mémoire partagée en fonction    Fonction renvoyant le nom du segment de mémoire partagée en fonction
Line 2324  nom_segment(unsigned char *chemin, pid_t Line 2544  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 2332  nom_segment(unsigned char *chemin, pid_t Line 2552  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 2342  nom_segment(unsigned char *chemin, pid_t Line 2562  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 2370  nom_segment(unsigned char *chemin, pid_t Line 2590  nom_segment(unsigned char *chemin, pid_t
 int  int
 envoi_signal_processus(pid_t pid, enum signaux_rpl signal)  envoi_signal_processus(pid_t pid, enum signaux_rpl signal)
 {  {
     int                             segment;  #   ifndef OS2
           int                         segment;
   #   endif
   
 #   ifndef IPCS_SYSV  #   ifndef IPCS_SYSV
 #       ifdef SEMAPHORES_NOMMES          sem_t                       *semaphore;
             sem_t                   *semaphore;          sem_t                       *signalisation;
 #       endif  
 #   else  #   else
         int                         desc;          sem_t                       *semaphore;
         key_t                       clef;          sem_t                       *signalisation;
   #       ifndef OS2
               int                     desc;
               key_t                   clef;
   #       endif
 #   endif  #   endif
   
     struct_queue_signaux            *queue;      struct_queue_signaux            *queue;
Line 2397  envoi_signal_processus(pid_t pid, enum s Line 2622  envoi_signal_processus(pid_t pid, enum s
             return(1);              return(1);
         }          }
   
 #       ifndef SEMAPHORES_NOMMES          while(sem_wait(semaphore_queue_signaux) != 0)
             if (sem_wait(&((*s_queue_signaux).semaphore)) != 0)  
 #       else  
             if (sem_wait(semaphore_queue_signaux) != 0)  
 #       endif  
         {          {
             return(1);              if (errno != EINTR)
               {
                   return(1);
               }
         }          }
   
         (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]          (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
Line 2415  envoi_signal_processus(pid_t pid, enum s Line 2639  envoi_signal_processus(pid_t pid, enum s
                 ((*s_queue_signaux).pointeur_ecriture + 1)                  ((*s_queue_signaux).pointeur_ecriture + 1)
                 % LONGUEUR_QUEUE_SIGNAUX;                  % LONGUEUR_QUEUE_SIGNAUX;
   
 #       ifndef SEMAPHORES_NOMMES  #       ifndef IPCS_SYSV
             if (sem_post(&((*s_queue_signaux).semaphore)) != 0)          if (msync(s_queue_signaux, sizeof(s_queue_signaux),
 #       else                  MS_ASYNC | MS_INVALIDATE) != 0)
             if (sem_post(semaphore_queue_signaux) != 0)          {
               return(1);
           }
 #       endif  #       endif
   
           if (sem_post(semaphore_queue_signaux) != 0)
           {
               return(1);
           }
   
           if (sem_post(semaphore_signalisation) != 0)
         {          {
             return(1);              return(1);
         }          }
Line 2434  envoi_signal_processus(pid_t pid, enum s Line 2667  envoi_signal_processus(pid_t pid, enum s
                 return(1);                  return(1);
             }              }
   
             if ((desc = open(nom, O_RDWR)) == -1)  #           ifndef OS2 // SysV
             {                  if ((desc = open(nom, O_RDWR)) == -1)
                 free(nom);                  {
                 return(1);                      sys_free(nom);
             }                      return(1);
                   }
   
             close(desc);                  close(desc);
   
             if ((clef = ftok(nom, 1)) == -1)                  if ((clef = ftok(nom, 1)) == -1)
             {                  {
                 free(nom);                      sys_free(nom);
                 return(1);                      return(1);
             }                  }
   
             free(nom);                  sys_free(nom);
   
             if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0)) == -1)                  if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0))
             {                          == -1)
                 return(1);                  {
             }                      return(1);
                   }
   
             queue = shmat(segment, NULL, 0);                  queue = shmat(segment, NULL, 0);
   #           else // OS/2
                   if (DosGetNamedSharedMem((PVOID) &queue, nom,
                           PAG_WRITE | PAG_READ) != 0)
                   {
                       sys_free(nom);
                       return(1);
                   }
   
                   sys_free(nom);
   #           endif
 #       else // POSIX  #       else // POSIX
             if ((nom = nom_segment(racine_segment, pid)) == NULL)              if ((nom = nom_segment(racine_segment, pid)) == NULL)
             {              {
Line 2464  envoi_signal_processus(pid_t pid, enum s Line 2709  envoi_signal_processus(pid_t pid, enum s
   
             if ((segment = shm_open(nom, O_RDWR, 0)) == -1)              if ((segment = shm_open(nom, O_RDWR, 0)) == -1)
             {              {
                 free(nom);                  sys_free(nom);
                 return(1);                  return(1);
             }              }
   
             free(nom);              sys_free(nom);
   
             if ((queue = mmap(NULL, sizeof(struct_queue_signaux),              if ((queue = mmap(NULL, sizeof(struct_queue_signaux),
                     PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0)) ==                      PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0)) ==
Line 2479  envoi_signal_processus(pid_t pid, enum s Line 2724  envoi_signal_processus(pid_t pid, enum s
             }              }
 #       endif  #       endif
   
             // À ce moment, le segment de mémoire partagée est projeté          // À ce moment, le segment de mémoire partagée est projeté
             // dans l'espace du processus.          // dans l'espace du processus.
   
 #       ifndef IPCS_SYSV // POSIX          if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)
 #           ifndef SEMAPHORES_NOMMES          {
                 if (sem_wait(&((*queue).semaphore)) != 0)              return(1);
                 {          }
                     return(1);  
                 }  
 #           else  
                 if ((semaphore = sem_open2(pid)) == SEM_FAILED)  
                 {  
                     return(1);  
                 }  
   
                 if (sem_wait(semaphore) != 0)          if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))
                 {                  == SEM_FAILED)
                     sem_close(semaphore);          {
                     return(1);              return(1);
                 }          }
 #           endif  
 #       else // IPCS_SYSV          while(sem_wait(semaphore) != 0)
             if (sem_wait(&((*queue).semaphore)) != 0)          {
               if (errno != EINTR)
             {              {
                   sem_close(semaphore);
                   sem_close(signalisation);
                 return(1);                  return(1);
             }              }
 #       endif          }
   
         (*queue).queue[(*queue).pointeur_ecriture].pid = getpid();          (*queue).queue[(*queue).pointeur_ecriture].pid = getpid();
         (*queue).queue[(*queue).pointeur_ecriture].signal = signal;          (*queue).queue[(*queue).pointeur_ecriture].signal = signal;
Line 2513  envoi_signal_processus(pid_t pid, enum s Line 2754  envoi_signal_processus(pid_t pid, enum s
         (*queue).pointeur_ecriture = ((*queue).pointeur_ecriture + 1)          (*queue).pointeur_ecriture = ((*queue).pointeur_ecriture + 1)
                 % LONGUEUR_QUEUE_SIGNAUX;                  % LONGUEUR_QUEUE_SIGNAUX;
   
 #       ifndef IPCS_SYSV // POSIX  #       ifndef IPCS_SYSV
 #           ifndef SEMAPHORES_NOMMES          if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
                 if (sem_post(&((*queue).semaphore)) != 0)          {
                 {              sem_close(semaphore);
                     return(1);              sem_close(signalisation);
                 }              return(1);
 #           else          }
                 if (sem_post(semaphore) != 0)  #       endif
                 {  
                     sem_close(semaphore);  
                     return(1);  
                 }  
   
                 if (sem_close(semaphore) != 0)          if (sem_post(semaphore) != 0)
                 {          {
                     return(1);              sem_close(semaphore);
                 }              sem_close(signalisation);
 #           endif              return(1);
           }
   
           if (sem_close(semaphore) != 0)
           {
               return(1);
           }
   
           if (sem_post(signalisation) != 0)
           {
               sem_close(signalisation);
               return(1);
           }
   
           if (sem_close(signalisation) != 0)
           {
               return(1);
           }
   
   #       ifndef IPCS_SYSV // POSIX
             if (munmap(queue, sizeof(struct_queue_signaux)) != 0)              if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
             {              {
                 close(segment);                  close(segment);
                 return(1);                  return(1);
             }              }
 #       else // IPCS_SYSV  #       else // IPCS_SYSV
             if (sem_post(&((*queue).semaphore)) != 0)  #           ifndef OS2 // SysV
             {                  if (shmdt(queue) != 0)
                 return(1);                  {
             }                      return(1);
                   }
             if (shmdt(queue) != 0)  #           else // OS/2
             {                  // Pendant de DosGetNamedSHaredMem()
                 return(1);  #           endif
             }  
 #       endif  #       endif
     }      }
   
Line 2587  envoi_signal_thread(pthread_t tid, enum Line 2841  envoi_signal_thread(pthread_t tid, enum
         return(1);          return(1);
     }      }
   
     if (pthread_mutex_lock(&mutex_interruptions) != 0)      s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
               .s_etat_processus;
   
       if (pthread_mutex_lock(&((*s_etat_processus).mutex_signaux)) != 0)
     {      {
         pthread_mutex_unlock(&mutex_liste_threads);          pthread_mutex_unlock(&mutex_liste_threads);
         return(1);          return(1);
     }      }
   
     s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))  
             .s_etat_processus;  
   
     (*s_etat_processus).signaux_en_queue      (*s_etat_processus).signaux_en_queue
             [(*s_etat_processus).pointeur_signal_ecriture] = signal;              [(*s_etat_processus).pointeur_signal_ecriture] = signal;
     (*s_etat_processus).pointeur_signal_ecriture =      (*s_etat_processus).pointeur_signal_ecriture =
             ((*s_etat_processus).pointeur_signal_ecriture + 1)              ((*s_etat_processus).pointeur_signal_ecriture + 1)
             % LONGUEUR_QUEUE_SIGNAUX;              % LONGUEUR_QUEUE_SIGNAUX;
   
     if (pthread_mutex_unlock(&mutex_interruptions) != 0)      if (pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux)) != 0)
     {      {
         pthread_mutex_unlock(&mutex_liste_threads);          pthread_mutex_unlock(&mutex_liste_threads);
         return(1);          return(1);
Line 2613  envoi_signal_thread(pthread_t tid, enum Line 2867  envoi_signal_thread(pthread_t tid, enum
         return(1);          return(1);
     }      }
   
       if (sem_post(semaphore_signalisation) != 0)
       {
           return(1);
       }
   
     return(0);      return(0);
 }  }
   
Line 2620  int Line 2879  int
 envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,  envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
         enum signaux_rpl signal)          enum signaux_rpl signal)
 {  {
     pthread_mutex_lock(&mutex_interruptions);      pthread_mutex_lock(&((*s_etat_processus_a_signaler).mutex_signaux));
     (*s_etat_processus_a_signaler).signaux_en_queue      (*s_etat_processus_a_signaler).signaux_en_queue
             [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =              [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =
             signal;              signal;
     (*s_etat_processus_a_signaler).pointeur_signal_ecriture =      (*s_etat_processus_a_signaler).pointeur_signal_ecriture =
             ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)              ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)
             % LONGUEUR_QUEUE_SIGNAUX;              % LONGUEUR_QUEUE_SIGNAUX;
     pthread_mutex_unlock(&mutex_interruptions);      pthread_mutex_unlock(&((*s_etat_processus_a_signaler).mutex_signaux));
   
       if (sem_post(semaphore_signalisation) != 0)
       {
           return(1);
       }
   
     return(0);      return(0);
 }  }
Line 2649  envoi_signal_contexte(struct_processus * Line 2913  envoi_signal_contexte(struct_processus *
 void  void
 creation_queue_signaux(struct_processus *s_etat_processus)  creation_queue_signaux(struct_processus *s_etat_processus)
 {  {
       pthread_attr_t                  attributs;
   
     unsigned char                   *nom;      unsigned char                   *nom;
   
     racine_segment = (*s_etat_processus).chemin_fichiers_temporaires;      racine_segment = (*s_etat_processus).chemin_fichiers_temporaires;
Line 2664  creation_queue_signaux(struct_processus Line 2930  creation_queue_signaux(struct_processus
         if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,          if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
                 S_IRUSR | S_IWUSR)) == -1)                  S_IRUSR | S_IWUSR)) == -1)
         {          {
             free(nom);              sys_free(nom);
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
             return;              return;
         }          }
   
         if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)          if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)
         {          {
             free(nom);              sys_free(nom);
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
             return;              return;
         }          }
Line 2683  creation_queue_signaux(struct_processus Line 2949  creation_queue_signaux(struct_processus
         {          {
             if (shm_unlink(nom) == -1)              if (shm_unlink(nom) == -1)
             {              {
                 free(nom);                  sys_free(nom);
                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;                  (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                 return;                  return;
             }              }
   
             free(nom);              sys_free(nom);
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
             return;              return;
         }          }
   
         free(nom);          sys_free(nom);
   
 #       ifndef SEMAPHORES_NOMMES          if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
             sem_init(&((*s_queue_signaux).semaphore), 1, 1);                  == SEM_FAILED)
 #       else          {
             if ((semaphore_queue_signaux = sem_init2(1, getpid()))              (*s_etat_processus).erreur_systeme = d_es_processus;
                     == SEM_FAILED)              return;
             {          }
                 (*s_etat_processus).erreur_systeme = d_es_processus;  
                 return;          if ((semaphore_signalisation = sem_init2(0, getpid(),
             }                  SEM_SIGNALISATION)) == SEM_FAILED)
 #       endif          {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           if ((semaphore_arret_signalisation = sem_init2(1, getpid(),
                   SEM_ARRET_SIGNALISATION)) == SEM_FAILED)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
         (*s_queue_signaux).pointeur_lecture = 0;          (*s_queue_signaux).pointeur_lecture = 0;
         (*s_queue_signaux).pointeur_ecriture = 0;          (*s_queue_signaux).pointeur_ecriture = 0;
   
         if (msync(s_queue_signaux, sizeof(struct_queue_signaux), 0))          (*s_queue_signaux).requete_arret = d_faux;
   
           if (msync(s_queue_signaux, sizeof(struct_queue_signaux), MS_SYNC))
         {          {
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
             return;              return;
Line 2745  creation_queue_signaux(struct_processus Line 3023  creation_queue_signaux(struct_processus
             }              }
   
             close(support);              close(support);
             free(nom);              sys_free(nom);
   
             if ((segment = shmget(clef, sizeof(struct_queue_signaux),              if ((segment = shmget(clef, sizeof(struct_queue_signaux),
                     IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)                      IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
Line 2770  creation_queue_signaux(struct_processus Line 3048  creation_queue_signaux(struct_processus
                 return;                  return;
             }              }
   
             sem_init(&((*s_queue_signaux).semaphore), 1, 1);              if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
                       == SEM_FAILED)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               if ((semaphore_signalisation = sem_init2(0, getpid(),
                       SEM_SIGNALISATION)) == SEM_FAILED)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
               if ((semaphore_arret_signalisation = sem_init2(1, getpid(),
                       SEM_ARRET_SIGNALISATION)) == SEM_FAILED)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
   
             (*s_queue_signaux).pointeur_lecture = 0;              (*s_queue_signaux).pointeur_lecture = 0;
             (*s_queue_signaux).pointeur_ecriture = 0;              (*s_queue_signaux).pointeur_ecriture = 0;
               (*s_queue_signaux).requete_arret = d_faux;
 #       else // OS/2  #       else // OS/2
             if ((nom = nom_segment(NULL, getpid())) == NULL)              if ((nom = nom_segment(NULL, getpid())) == NULL)
             {              {
Line 2780  creation_queue_signaux(struct_processus Line 3079  creation_queue_signaux(struct_processus
                 return;                  return;
             }              }
   
             if (DosAllocSharedMem(&ptr_os2, nom, nombre_queues *              if (DosAllocSharedMem((PVOID) &s_queue_signaux, nom,
                     ((2 * longueur_queue) + 4) * sizeof(int),                      sizeof(struct_queue_signaux),
                     PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)                      PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
             {              {
                 free(nom);                  sys_free(nom);
                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;                  (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                 return;                  return;
             }              }
   
             free(nom);              sys_free(nom);
             fifos = ptr_os2;  
               sem_init(&((*s_queue_signaux).semaphore), 1, 1);
               sem_init(&((*s_queue_signaux).signalisation), 1, 0);
               sem_init(&((*s_queue_signaux).arret_signalisation), 1, 1);
   
               (*s_queue_signaux).pointeur_lecture = 0;
               (*s_queue_signaux).pointeur_ecriture = 0;
               (*s_queue_signaux).requete_arret = d_faux;
 #       endif  #       endif
 #   endif  #   endif
   
       // Lancement du thread de récupération des signaux.
   
       if (pthread_attr_init(&attributs) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
       if (pthread_attr_setdetachstate(&attributs,
               PTHREAD_CREATE_JOINABLE) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
   #   ifdef SCHED_OTHER
       if (pthread_attr_setschedpolicy(&attributs, SCHED_OTHER) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   #   endif
   
   #   ifdef PTHREAD_EXPLICIT_SCHED
       if (pthread_attr_setinheritsched(&attributs, PTHREAD_EXPLICIT_SCHED) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   #   endif
   
   #   ifdef PTHREAD_SCOPE_SYSTEM
       if (pthread_attr_setscope(&attributs, PTHREAD_SCOPE_SYSTEM) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   #   endif
   
       if (pthread_attr_destroy(&attributs) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
       if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs,
               thread_surveillance_signaux, s_etat_processus) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
     return;      return;
 }  }
   
Line 2814  creation_queue_signaux(struct_processus Line 3172  creation_queue_signaux(struct_processus
 void  void
 liberation_queue_signaux(struct_processus *s_etat_processus)  liberation_queue_signaux(struct_processus *s_etat_processus)
 {  {
       sem_wait(semaphore_arret_signalisation);
       (*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);
       pthread_join((*s_queue_signaux).thread_signaux, NULL);
   
 #   ifdef IPCS_SYSV // SystemV  #   ifdef IPCS_SYSV // SystemV
 #       ifndef OS2  #       ifndef OS2
             if (shmdt(s_queue_signaux) == -1)              if (shmdt(s_queue_signaux) == -1)
Line 2824  liberation_queue_signaux(struct_processu Line 3196  liberation_queue_signaux(struct_processu
 #       else // OS/2  #       else // OS/2
 #       endif  #       endif
 #   else // POSIX  #   else // POSIX
 #       ifndef SEMAPHORES_NOMMES          sem_close(semaphore_queue_signaux);
             sem_close(&((*s_queue_signaux).semaphore));          sem_close(semaphore_signalisation);
 #       else          sem_close(semaphore_arret_signalisation);
             sem_close(semaphore_queue_signaux);  
 #       endif  
   
         if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)          if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
         {          {
Line 2859  liberation_queue_signaux(struct_processu Line 3229  liberation_queue_signaux(struct_processu
 void  void
 destruction_queue_signaux(struct_processus *s_etat_processus)  destruction_queue_signaux(struct_processus *s_etat_processus)
 {  {
     unsigned char       *nom;  #   ifndef OS2
           unsigned char       *nom;
   #   endif
   
       sem_wait(semaphore_arret_signalisation);
   
       (*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);
       pthread_join((*s_queue_signaux).thread_signaux, NULL);
   
 #   ifdef IPCS_SYSV // SystemV  #   ifdef IPCS_SYSV // SystemV
 #       ifndef OS2  #       ifndef OS2
             // Il faut commencer par éliminer le sémaphore.              // Il faut commencer par éliminer le sémaphore.
   
             if (semctl((*s_queue_signaux).semaphore.sem, 0, IPC_RMID) == -1)              if (semctl((*semaphore_queue_signaux).sem, 0, IPC_RMID) == -1)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                 return;                  return;
             }              }
   
             unlink((*s_queue_signaux).semaphore.path);              unlink((*semaphore_queue_signaux).path);
               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)              if (shmdt(s_queue_signaux) == -1)
             {              {
Line 2893  destruction_queue_signaux(struct_process Line 3299  destruction_queue_signaux(struct_process
             }              }
   
             unlink(nom);              unlink(nom);
             free(nom);              sys_free(nom);
 #       else  #       else
             if (DosFreeMem(fifos) != 0)              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;                  (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                 return;                  return;
             }              }
   
         // FERMER LE FICHIER  
   
 #       endif  #       endif
 #   else // POSIX  #   else // POSIX
 #       ifndef SEMAPHORES_NOMMES          sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);
             sem_close(&((*s_queue_signaux).semaphore));          sem_destroy2(semaphore_signalisation, getpid(), SEM_SIGNALISATION);
             sem_destroy(&((*s_queue_signaux).semaphore));          sem_destroy2(semaphore_arret_signalisation, getpid(),
 #       else                  SEM_ARRET_SIGNALISATION);
             sem_close(semaphore_queue_signaux);  
             sem_destroy2(semaphore_queue_signaux, getpid());  
 #       endif  
   
         if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)          if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
         {          {
Line 2929  destruction_queue_signaux(struct_process Line 3338  destruction_queue_signaux(struct_process
   
         if (shm_unlink(nom) != 0)          if (shm_unlink(nom) != 0)
         {          {
             free(nom);              sys_free(nom);
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
             return;              return;
         }          }
   
         free(nom);          sys_free(nom);
 #   endif  #   endif
   
     return;      return;

Removed from v.1.77  
changed lines
  Added in v.1.157


CVSweb interface <joel.bertrand@systella.fr>