Diff for /rpl/src/interruptions.c between versions 1.39 and 1.66

version 1.39, 2010/09/02 07:51:48 version 1.66, 2011/09/10 20:45:06
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.0.19    RPL/2 (R) version 4.1.3
   Copyright (C) 1989-2010 Dr. BERTRAND Joël    Copyright (C) 1989-2011 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
   
Line 183  insertion_thread_surveillance(struct_pro Line 183  insertion_thread_surveillance(struct_pro
         }          }
     }      }
   
     pthread_mutex_lock(&((*s_argument_thread).mutex));      pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references));
     (*s_argument_thread).nombre_references++;      (*s_argument_thread).nombre_references++;
     pthread_mutex_unlock(&((*s_argument_thread).mutex));      pthread_mutex_unlock(&((*s_argument_thread).mutex_nombre_references));
   
     (*l_nouvel_objet).suivant = liste_threads_surveillance;      (*l_nouvel_objet).suivant = liste_threads_surveillance;
     (*l_nouvel_objet).donnee = (void *) s_argument_thread;      (*l_nouvel_objet).donnee = (void *) s_argument_thread;
Line 378  retrait_thread_surveillance(struct_proce Line 378  retrait_thread_surveillance(struct_proce
         (*l_element_precedent).suivant = (*l_element_courant).suivant;          (*l_element_precedent).suivant = (*l_element_courant).suivant;
     }      }
   
     if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)      if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
               != 0)
     {      {
 #       ifndef SEMAPHORES_NOMMES  #       ifndef SEMAPHORES_NOMMES
         sem_post(&semaphore_liste_threads);          sem_post(&semaphore_liste_threads);
Line 400  retrait_thread_surveillance(struct_proce Line 401  retrait_thread_surveillance(struct_proce
   
     if ((*s_argument_thread).nombre_references == 0)      if ((*s_argument_thread).nombre_references == 0)
     {      {
         if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)          if (pthread_mutex_unlock(&((*s_argument_thread)
                   .mutex_nombre_references)) != 0)
         {          {
 #           ifndef SEMAPHORES_NOMMES  #           ifndef SEMAPHORES_NOMMES
             sem_post(&semaphore_liste_threads);              sem_post(&semaphore_liste_threads);
Line 415  retrait_thread_surveillance(struct_proce Line 417  retrait_thread_surveillance(struct_proce
         }          }
   
         pthread_mutex_destroy(&((*s_argument_thread).mutex));          pthread_mutex_destroy(&((*s_argument_thread).mutex));
           pthread_mutex_destroy(&((*s_argument_thread).mutex_nombre_references));
         free(s_argument_thread);          free(s_argument_thread);
     }      }
     else      else
     {      {
         if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)          if (pthread_mutex_unlock(&((*s_argument_thread)
                   .mutex_nombre_references)) != 0)
         {          {
 #           ifndef SEMAPHORES_NOMMES  #           ifndef SEMAPHORES_NOMMES
             sem_post(&semaphore_liste_threads);              sem_post(&semaphore_liste_threads);
Line 676  liberation_threads(struct_processus *s_e Line 680  liberation_threads(struct_processus *s_e
                 s_argument_thread = (struct_descripteur_thread *)                  s_argument_thread = (struct_descripteur_thread *)
                         (*((struct_liste_chainee *) element_courant)).donnee;                          (*((struct_liste_chainee *) element_courant)).donnee;
   
                 if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)                  if (pthread_mutex_lock(&((*s_argument_thread)
                           .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);                      sem_post(&semaphore_liste_threads);
Line 700  liberation_threads(struct_processus *s_e Line 705  liberation_threads(struct_processus *s_e
                     close((*s_argument_thread)                      close((*s_argument_thread)
                             .pipe_nombre_interruptions_attente[0]);                              .pipe_nombre_interruptions_attente[0]);
   
                     if (pthread_mutex_unlock(&((*s_argument_thread).mutex))                      if (pthread_mutex_unlock(&((*s_argument_thread)
                             != 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);                          sem_post(&semaphore_liste_threads);
Line 709  liberation_threads(struct_processus *s_e Line 714  liberation_threads(struct_processus *s_e
                     }                      }
   
                     pthread_mutex_destroy(&((*s_argument_thread).mutex));                      pthread_mutex_destroy(&((*s_argument_thread).mutex));
                       pthread_mutex_destroy(&((*s_argument_thread)
                               .mutex_nombre_references));
   
                     if ((*s_argument_thread).processus_detache == d_faux)                      if ((*s_argument_thread).processus_detache == d_faux)
                     {                      {
Line 723  liberation_threads(struct_processus *s_e Line 730  liberation_threads(struct_processus *s_e
                 }                  }
                 else                  else
                 {                  {
                     if (pthread_mutex_unlock(&((*s_argument_thread).mutex))                      if (pthread_mutex_unlock(&((*s_argument_thread)
                             != 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);                          sem_post(&semaphore_liste_threads);
Line 796  liberation_threads(struct_processus *s_e Line 803  liberation_threads(struct_processus *s_e
                 }                  }
             }              }
   
             for(i = 0; i < (*s_etat_processus).nombre_variables; i++)              liberation_arbre_variables(s_etat_processus,
             {                      (*s_etat_processus).s_arbre_variables, d_faux);
                 pthread_mutex_trylock(&((*(*s_etat_processus)  
                         .s_liste_variables[i].objet).mutex));  
                 pthread_mutex_unlock(&((*(*s_etat_processus)  
                         .s_liste_variables[i].objet).mutex));  
   
                 // Les variables de niveau 0 sont des définitions qui  
                 // ne sont pas copiées entre threads.  
                 if ((*s_etat_processus).s_liste_variables[i].niveau > 0)  
                 {  
                     liberation(s_etat_processus,  
                             (*s_etat_processus).s_liste_variables[i].objet);  
                 }  
   
                 free((*s_etat_processus).s_liste_variables[i].nom);  
             }  
   
             free((*s_etat_processus).s_liste_variables);  
   
             for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)              for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
             {              {
Line 1328  liberation_threads(struct_processus *s_e Line 1318  liberation_threads(struct_processus *s_e
             sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork);              sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork);
 #           endif  #           endif
   
               liberation_contexte_cas(s_etat_processus);
             free(s_etat_processus);              free(s_etat_processus);
   
             s_etat_processus = candidat;              s_etat_processus = candidat;
Line 1350  liberation_threads(struct_processus *s_e Line 1341  liberation_threads(struct_processus *s_e
         s_argument_thread = (struct_descripteur_thread *)          s_argument_thread = (struct_descripteur_thread *)
                 (*l_element_courant).donnee;                  (*l_element_courant).donnee;
   
         if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)          if (pthread_mutex_lock(&((*s_argument_thread).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);              sem_post(&semaphore_liste_threads);
Line 1373  liberation_threads(struct_processus *s_e Line 1365  liberation_threads(struct_processus *s_e
             close((*s_argument_thread).pipe_interruptions[0]);              close((*s_argument_thread).pipe_interruptions[0]);
             close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);              close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
   
             if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)              if (pthread_mutex_unlock(&((*s_argument_thread)
                       .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);                  sem_post(&semaphore_liste_threads);
Line 1381  liberation_threads(struct_processus *s_e Line 1374  liberation_threads(struct_processus *s_e
             }              }
   
             pthread_mutex_destroy(&((*s_argument_thread).mutex));              pthread_mutex_destroy(&((*s_argument_thread).mutex));
               pthread_mutex_destroy(&((*s_argument_thread)
                       .mutex_nombre_references));
   
             if ((*s_argument_thread).processus_detache == d_faux)              if ((*s_argument_thread).processus_detache == d_faux)
             {              {
Line 1394  liberation_threads(struct_processus *s_e Line 1389  liberation_threads(struct_processus *s_e
         }          }
         else          else
         {          {
             if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)              if (pthread_mutex_unlock(&((*s_argument_thread)
                       .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);                  sem_post(&semaphore_liste_threads);
Line 1461  recherche_thread(pid_t pid, pthread_t ti Line 1457  recherche_thread(pid_t pid, pthread_t ti
     return(s_etat_processus);      return(s_etat_processus);
 }  }
   
 static logical1  static struct_processus *
 recherche_thread_principal(pid_t pid, pthread_t *thread)  recherche_thread_principal(pid_t pid)
 {  {
     volatile struct_liste_chainee_volatile      *l_element_courant;      volatile struct_liste_chainee_volatile      *l_element_courant;
   
Line 1486  recherche_thread_principal(pid_t pid, pt Line 1482  recherche_thread_principal(pid_t pid, pt
          * Le processus n'existe plus. On ne distribue aucun signal.           * Le processus n'existe plus. On ne distribue aucun signal.
          */           */
   
         return(d_faux);          return(NULL);
     }      }
   
     (*thread) = (*((struct_thread *) (*l_element_courant).donnee)).tid;      return((*((struct_thread *) (*l_element_courant).donnee))
               .s_etat_processus);
     return(d_vrai);  
 }  }
   
   
Line 1592  verrouillage_gestionnaire_signaux() Line 1587  verrouillage_gestionnaire_signaux()
         // ce que ce soit possible.          // ce que ce soit possible.
   
 #       ifndef SEMAPHORES_NOMMES  #       ifndef SEMAPHORES_NOMMES
         while(sem_trywait(&semaphore_liste_threads) == -1)          while(sem_wait(&semaphore_liste_threads) == -1)
 #       else  #       else
         while(sem_trywait(semaphore_liste_threads) == -1)          while(sem_wait(semaphore_liste_threads) == -1)
 #       endif  #       endif
         {          {
             if ((errno != EINTR) && (errno != EAGAIN))              if (errno != EINTR)
             {              {
                 pthread_sigmask(SIG_SETMASK, &oldset, NULL);                  pthread_sigmask(SIG_SETMASK, &oldset, NULL);
   
Line 1613  verrouillage_gestionnaire_signaux() Line 1608  verrouillage_gestionnaire_signaux()
                 BUG(1, uprintf("Lock error !\n"));                  BUG(1, uprintf("Lock error !\n"));
                 return;                  return;
             }              }
   
             sched_yield();  
         }          }
     }      }
   
Line 1724  deverrouillage_gestionnaire_signaux() Line 1717  deverrouillage_gestionnaire_signaux()
     return;      return;
 }  }
   
 void  #define test_signal(signal) \
 interruption1(SIGHANDLER_ARGS)      if (signal_test == SIGTEST) \
       { signal_test = initialisation_queue_interruptions(signal); return; }
   
   /*
    * Les interruptions sont mise en mémoire puis traitées depuis
    * la fonction scrutation_injection() parce que les fonctions pthread*()
    * ne sont pas 'async signal safe'.
    *
    * Les interruptions sont ainsi empilées dans un buffer circulaire puis
    * traitées au fur et à mesure.
    */
   
   static struct
 {  {
     pid_t                   pid;  #   define                  SIGNAL_MAX      32
   #   define                  SIGNAL_BUFFER   1024
   #   define                  ECRITURE        0
   #   define                  LECTURE         1
   
     pthread_t               thread;      sig_atomic_t            nombre_interruptions_en_queue;
       int                     pointeur[SIGNAL_MAX][2];
   
     struct_processus        *s_etat_processus;      pid_t                   pid[SIGNAL_MAX][SIGNAL_BUFFER];
   } queue_interruptions;
   
     volatile sig_atomic_t   exclusion = 0;  pthread_mutex_t             mutex_signal = PTHREAD_MUTEX_INITIALIZER;
   
     verrouillage_gestionnaire_signaux();  static inline int
   initialisation_queue_interruptions(int signal)
   {
       int         i;
   
 #   ifdef _BROKEN_SIGINFO      if (signal > SIGNAL_MAX)
     if (signal == SIGINT)  
     {      {
         // Si l'interruption provient du clavier, il n'y a pas eu d'appel          return(signal + 1);
         // à queue_in().  
   
         pid = getpid();  
     }      }
     else  
       queue_interruptions.nombre_interruptions_en_queue = 0;
   
       for(i = 0; i < SIGNAL_MAX; i++)
     {      {
         pid = origine_signal(signal);          queue_interruptions.pointeur[i][ECRITURE] = 0;
           queue_interruptions.pointeur[i][LECTURE] = 0;
     }      }
   
       return(signal);
   }
   
   void
   interruption1(SIGHANDLER_ARGS)
   {
       pid_t               pid;
   
       test_signal(signal);
   
   #   ifdef _BROKEN_SIGINFO
           if ((signal == SIGINT) || (signal == SIGTERM))
           {
               // Si l'interruption provient du clavier, il n'y a pas eu d'appel
               // à queue_in().
   
               pid = getpid();
           }
           else
           {
               pid = origine_signal(signal);
           }
 #   else  #   else
     if (siginfo != NULL)  
     {      /*
         pid = (*siginfo).si_pid;       * Une vieille spécification POSIX permet au pointeur siginfo
     }       * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
     else       * Solaris suit en particulier cette spécification.
     {       */
         pid = getpid();  
     }          if (siginfo != NULL)
           {
               pid = (*siginfo).si_pid;
           }
           else
           {
               pid = getpid();
           }
 #   endif  #   endif
   
       queue_interruptions.pid[signal][queue_interruptions.pointeur
               [signal][ECRITURE]] = pid;
       queue_interruptions.pointeur[signal][ECRITURE] =
               (queue_interruptions.pointeur[signal][ECRITURE] + 1)
               % SIGNAL_BUFFER;
       queue_interruptions.nombre_interruptions_en_queue++;
       return;
   }
   
   static void
   corps_interruption1(struct_processus *s_etat_processus, int signal, pid_t pid)
   {
       volatile sig_atomic_t   exclusion = 0;
   
       struct_processus        *s_thread_principal;
   
       verrouillage_gestionnaire_signaux();
   
     switch(signal)      switch(signal)
     {      {
         case SIGALRM :          case SIGALRM :
         {          {
             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] SIGALRM (thread %llu)\n", (int) getpid(),                      printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
Line 1792  interruption1(SIGHANDLER_ARGS) Line 1846  interruption1(SIGHANDLER_ARGS)
             }              }
             else              else
             {              {
                 if (recherche_thread_principal(getpid(), &thread) == d_vrai)                  if ((s_thread_principal = recherche_thread_principal(getpid()))
                           != NULL)
                 {                  {
                     pthread_kill(thread, signal);                      while((*s_etat_processus).signal_a_traiter == d_vrai);
                       (*s_etat_processus).signal = signal;
                       (*s_etat_processus).origine_signal = getpid();
                       (*s_etat_processus).signal_a_traiter = d_vrai;
                 }                  }
             }              }
   
Line 1802  interruption1(SIGHANDLER_ARGS) Line 1860  interruption1(SIGHANDLER_ARGS)
         }          }
   
         case SIGINT :          case SIGINT :
           case SIGTERM :
         {          {
             /*  
              * Une vieille spécification POSIX permet au pointeur siginfo  
              * d'être nul dans le cas d'un ^C envoyé depuis le clavier.  
              * Solaris suit en particulier cette spécification.  
              */  
   
 #           ifndef _BROKEN_SIGINFO  
             if (siginfo == NULL)  
             {  
                 kill(getpid(), signal);  
             }  
             else  
 #           endif  
             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] SIGINT (thread %llu)\n", (int) getpid(),                      if (signal == SIGINT)
                             (unsigned long long) pthread_self());                      {
                           printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
                                   (unsigned long long) pthread_self());
                       }
                       else
                       {
                           printf("[%d] SIGTERM (thread %llu)\n", (int) getpid(),
                                   (unsigned long long) pthread_self());
                       }
   
                     fflush(stdout);                      fflush(stdout);
                 }                  }
   
Line 1850  interruption1(SIGHANDLER_ARGS) Line 1898  interruption1(SIGHANDLER_ARGS)
                         return;                          return;
                     }                      }
   
                     if (strncmp(getenv("LANG"), "fr", 2) == 0)                      if (signal == SIGINT)
                     {                      {
                         printf("+++Interruption\n");                          if (strncmp(getenv("LANG"), "fr", 2) == 0)
                     }                          {
                     else                              printf("+++Interruption\n");
                     {                          }
                         printf("+++Interrupt\n");                          else
                     }                          {
                               printf("+++Interrupt\n");
                           }
   
                     fflush(stdout);                          fflush(stdout);
                       }
   
                     (*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;
Line 1869  interruption1(SIGHANDLER_ARGS) Line 1920  interruption1(SIGHANDLER_ARGS)
             }              }
             else              else
             {              {
                 if (recherche_thread_principal(getpid(), &thread) == d_vrai)                  if ((s_thread_principal = recherche_thread_principal(getpid()))
                           != NULL)
                 {                  {
                     pthread_kill(thread, signal);                      while((*s_etat_processus).signal_a_traiter == d_vrai);
                       (*s_etat_processus).signal = signal;
                       (*s_etat_processus).origine_signal = getpid();
                       (*s_etat_processus).signal_a_traiter = d_vrai;
                 }                  }
             }              }
   
Line 1893  interruption1(SIGHANDLER_ARGS) Line 1948  interruption1(SIGHANDLER_ARGS)
 void  void
 interruption2(SIGHANDLER_ARGS)  interruption2(SIGHANDLER_ARGS)
 {  {
     pid_t                   pid;      pid_t               pid;
   
     pthread_t               thread;  
   
     struct_processus        *s_etat_processus;  
   
     verrouillage_gestionnaire_signaux();      test_signal(signal);
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
     pid = origine_signal(signal);      pid = origine_signal(signal);
Line 1914  interruption2(SIGHANDLER_ARGS) Line 1965  interruption2(SIGHANDLER_ARGS)
     }      }
 #   endif  #   endif
   
 #   ifndef _BROKEN_SIGINFO      queue_interruptions.pid[signal][queue_interruptions.pointeur
               [signal][ECRITURE]] = pid;
       queue_interruptions.pointeur[signal][ECRITURE] =
               (queue_interruptions.pointeur[signal][ECRITURE] + 1)
               % SIGNAL_BUFFER;
   
       /*
        * 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.
        */
   
     if (siginfo == NULL)      if (siginfo == NULL)
     {      {
         /*          queue_interruptions.pid[SIGHUP][queue_interruptions.pointeur
          * Le signal SIGFSTP provient de la mort du processus de contrôle.                  [SIGHUP][ECRITURE]] = pid;
          * Sous certains systèmes (Linux...), la mort du terminal de contrôle          queue_interruptions.pointeur[SIGHUP][ECRITURE] =
          * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres                  (queue_interruptions.pointeur[SIGHUP][ECRITURE] + 1)
          * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo                  % SIGNAL_BUFFER;
          * non initialisée (pointeur NULL) issue de TERMIO.          queue_interruptions.nombre_interruptions_en_queue += 2;
          */  
   
         if (recherche_thread_principal(getpid(), &thread) == d_vrai)  
         {  
             pthread_kill(thread, SIGHUP);  
             deverrouillage_gestionnaire_signaux();  
             return;  
         }  
     }      }
     else  
 #   endif      return;
   }
   
   static void
   corps_interruption2(struct_processus *s_etat_processus, int signal, pid_t pid)
   {
       struct_processus        *s_thread_principal;
   
       verrouillage_gestionnaire_signaux();
   
     if (pid == getpid())      if (pid == getpid())
     {      {
         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))  
                 == NULL)  
         {  
             deverrouillage_gestionnaire_signaux();  
             return;  
         }  
   
         /*          /*
          *  0 => fonctionnement normal           *  0 => fonctionnement normal
          * -1 => requête           * -1 => requête
Line 1969  interruption2(SIGHANDLER_ARGS) Line 2027  interruption2(SIGHANDLER_ARGS)
     {      {
         // Envoi d'un signal au thread maître du groupe.          // Envoi d'un signal au thread maître du groupe.
   
         if (recherche_thread_principal(getpid(), &thread) == d_vrai)          if ((s_thread_principal = recherche_thread_principal(getpid()))
                   != NULL)
         {          {
             pthread_kill(thread, SIGTSTP);              while((*s_etat_processus).signal_a_traiter == d_vrai);
             deverrouillage_gestionnaire_signaux();              (*s_etat_processus).signal = signal;
             return;              (*s_etat_processus).origine_signal = getpid();
               (*s_etat_processus).signal_a_traiter = d_vrai;
         }          }
     }      }
   
Line 1984  interruption2(SIGHANDLER_ARGS) Line 2044  interruption2(SIGHANDLER_ARGS)
 void  void
 interruption3(SIGHANDLER_ARGS)  interruption3(SIGHANDLER_ARGS)
 {  {
     pid_t                   pid;      // 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.
   
     struct_processus        *s_etat_processus;      unsigned char       message[] = "+++System : Uncaught access violation\n"
                                   "+++System : Aborting !\n;
   
     static int              compteur = 0;      if (pid_processus_pere == getpid())
       {
           kill(pid_processus_pere, SIGALRM);
       }
   
     verrouillage_gestionnaire_signaux();      write(STDERR_FILENO, message, strlen(message));
       _exit(EXIT_FAILURE);
   }
   
 #   ifdef _BROKEN_SIGINFO  void INTERRUPTION3_A_FIXER()
     pid = origine_signal(signal);  {
 #   else      pthread_t               thread;
     pid = (*siginfo).si_pid;  
 #   endif      struct_processus        *s_etat_processus;
   
       test_signal(signal);
       verrouillage_gestionnaire_signaux();
   
     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)      if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
     {      {
Line 2022  interruption3(SIGHANDLER_ARGS) Line 2093  interruption3(SIGHANDLER_ARGS)
         // Segfault dans une routine interne          // Segfault dans une routine interne
         if (strncmp(getenv("LANG"), "fr", 2) == 0)          if (strncmp(getenv("LANG"), "fr", 2) == 0)
         {          {
             printf("+++Système : Violation d'accès (dépassement de pile)\n");              printf("+++Système : Violation d'accès\n");
         }          }
         else          else
         {          {
             printf("+++System : Access violation (stack overflow)\n");              printf("+++System : Access violation\n");
         }          }
   
         fflush(stdout);          fflush(stdout);
   
         compteur++;          (*s_etat_processus).compteur_violation_d_acces++;
   
         if (compteur > 1)          if ((*s_etat_processus).compteur_violation_d_acces > 1)
         {          {
               // 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
               // récupérable et on sort autoritairement du programme. Il peut
               // rester des processus orphelins en attente !
   
               if (strncmp(getenv("LANG"), "fr", 2) == 0)
               {
                   printf("+++Système : Violation d'accès, tentative de "
                           "terminaison de la tâche\n");
                   printf("             (defauts multiples)\n");
               }
               else
               {
                   printf("+++System : Access violation, trying to kill task "
                           "(multiple defaults)\n");
               }
   
               fflush(stdout);
   
             deverrouillage_gestionnaire_signaux();              deverrouillage_gestionnaire_signaux();
             exit(EXIT_FAILURE);              exit(EXIT_FAILURE);
         }          }
         else          else
         {          {
               // Première erreur de segmentation. On essaie de terminer
               // proprement le thread ou le processus. Le signal ne peut être
               // envoyé que depuis le même processus.
   
               if (recherche_thread_principal(getpid(), &thread) == d_vrai)
               {
                   if (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();              deverrouillage_gestionnaire_signaux();
             longjmp(contexte_initial, -1);              longjmp(contexte_initial, -1);
         }          }
Line 2052  interruption3(SIGHANDLER_ARGS) Line 2178  interruption3(SIGHANDLER_ARGS)
 void  void
 interruption4(SIGHANDLER_ARGS)  interruption4(SIGHANDLER_ARGS)
 {  {
     pid_t                   pid;  
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       test_signal(signal);
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  
     pid = origine_signal(signal);  
 #   else  
     pid = (*siginfo).si_pid;  
 #   endif  
   
     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();
Line 2094  interruption5(SIGHANDLER_ARGS) Line 2213  interruption5(SIGHANDLER_ARGS)
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       test_signal(signal);
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
Line 2160  interruption5(SIGHANDLER_ARGS) Line 2280  interruption5(SIGHANDLER_ARGS)
 void  void
 interruption6(SIGHANDLER_ARGS)  interruption6(SIGHANDLER_ARGS)
 {  {
     pid_t                   pid;  
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       test_signal(signal);
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  
     pid = origine_signal(signal);  
 #   else  
     pid = (*siginfo).si_pid;  
 #   endif  
   
     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();
Line 2192  interruption6(SIGHANDLER_ARGS) Line 2305  interruption6(SIGHANDLER_ARGS)
 void  void
 interruption7(SIGHANDLER_ARGS)  interruption7(SIGHANDLER_ARGS)
 {  {
     pid_t                   pid;  
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       test_signal(signal);
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  
     pid = origine_signal(signal);  
 #   else  
     pid = (*siginfo).si_pid;  
 #   endif  
   
     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();
Line 2233  interruption8(SIGHANDLER_ARGS) Line 2339  interruption8(SIGHANDLER_ARGS)
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       test_signal(signal);
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
Line 2279  interruption8(SIGHANDLER_ARGS) Line 2386  interruption8(SIGHANDLER_ARGS)
 void  void
 interruption9(SIGHANDLER_ARGS)  interruption9(SIGHANDLER_ARGS)
 {  {
     pid_t                   pid;  
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       test_signal(signal);
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  
     pid = origine_signal(signal);  
 #   else  
     pid = (*siginfo).si_pid;  
 #   endif  
   
     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();
Line 2324  interruption10(SIGHANDLER_ARGS) Line 2424  interruption10(SIGHANDLER_ARGS)
 {  {
     file                    *fichier;      file                    *fichier;
   
     pid_t                   pid;  
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
     unsigned char           nom[8 + 64 + 1];      unsigned char           nom[8 + 64 + 1];
   
       test_signal(signal);
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  
     pid = origine_signal(signal);  
 #   else  
     pid = (*siginfo).si_pid;  
 #   endif  
   
     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();
Line 2377  interruption11(SIGHANDLER_ARGS) Line 2470  interruption11(SIGHANDLER_ARGS)
   
     struct_processus        *s_etat_processus;      struct_processus        *s_etat_processus;
   
       test_signal(signal);
     verrouillage_gestionnaire_signaux();      verrouillage_gestionnaire_signaux();
   
 #   ifdef _BROKEN_SIGINFO  #   ifdef _BROKEN_SIGINFO
Line 2463  traitement_exceptions_gsl(const char *re Line 2557  traitement_exceptions_gsl(const char *re
     return;      return;
 }  }
   
   static inline void
   structation_interruptions_elementaires(struct_processus *s_etat_processus,
           int signal, pid_t pid)
   {
       switch(signal)
       {
           case SIGINT:
           case SIGTERM:
           case SIGALRM:
           {
               corps_interruption1(s_etat_processus, signal, pid);
               break;
           }
   
           case SIGTSTP:
           {
               corps_interruption2(s_etat_processus, signal, pid);
           }
       }
   
       return;
   }
   
   void
   scrutation_interruptions(struct_processus *s_etat_processus)
   {
       int             i;
   
       // Interruption par processus.
   
       if (pthread_mutex_lock(&mutex_signal) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
       if (queue_interruptions.nombre_interruptions_en_queue > 0)
       {
           for(i = 0; i < SIGNAL_MAX; i++)
           {
               if ((queue_interruptions.pointeur[i][ECRITURE] -
                       queue_interruptions.pointeur[i][LECTURE]) != 0)
               {
                   // Il y a une interruption dans la queue.
   
                   queue_interruptions.nombre_interruptions_en_queue--;
                   scrutation_interruptions_elementaires(s_etat_processus, i,
                           queue_interruptions.pid[signal]
                           [queue_interruptions.pointeur[signal][LECTURE]]);
                   queue_interruptions.pointeur[signal][LECTURE] =
                           (queue_interruptions.pointeur[signal][LECTURE] + 1)
                           % SIGNAL_BUFFER;
               }
           }
       }
   
       if (pthread_mutex_unlock(&mutex_signal) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
       // Interruption par thread
   
       if ((*s_etat_processus).signal_a_traiter == d_vrai)
       {
           (*s_etat_processus).signal_a_traiter = d_faux;
           scrutation_interruptions_elementaires(s_etat_processus,
                   (*s_etat_processus).signal, (*s_etat_processus).origine_signal);
       }
   
       return;
   }
   
 // vim: ts=4  // vim: ts=4

Removed from v.1.39  
changed lines
  Added in v.1.66


CVSweb interface <joel.bertrand@systella.fr>