Diff for /rpl/src/interruptions.c between versions 1.9 and 1.20

version 1.9, 2010/04/21 13:45:50 version 1.20, 2010/06/04 07:48:20
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.0.15    RPL/2 (R) version 4.0.16
   Copyright (C) 1989-2010 Dr. BERTRAND Joël    Copyright (C) 1989-2010 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
Line 82  insertion_thread(struct_processus *s_eta Line 82  insertion_thread(struct_processus *s_eta
     sigfillset(&set);      sigfillset(&set);
     pthread_sigmask(SIG_BLOCK, &set, &oldset);      pthread_sigmask(SIG_BLOCK, &set, &oldset);
   
 #   ifndef SEMAPHORES_NOMMES  
     while(sem_wait(&semaphore_liste_threads) == -1)  
 #   else  
     while(sem_wait(semaphore_liste_threads) == -1)  
 #   endif  
     {  
         if (errno != EINTR)  
         {  
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
             sigpending(&set);  
   
             (*s_etat_processus).erreur_systeme = d_es_processus;  
             return;  
         }  
     }  
   
     if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))      if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
             == NULL)              == NULL)
     {      {
 #       ifndef SEMAPHORES_NOMMES  
         sem_post(&semaphore_liste_threads);  
 #       else  
         sem_post(semaphore_liste_threads);  
 #       endif  
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);          pthread_sigmask(SIG_SETMASK, &oldset, NULL);
         sigpending(&set);          sigpending(&set);
   
Line 113  insertion_thread(struct_processus *s_eta Line 92  insertion_thread(struct_processus *s_eta
         return;          return;
     }      }
   
     (*l_nouvel_objet).suivant = liste_threads;  
   
     if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)      if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)
     {      {
 #       ifndef SEMAPHORES_NOMMES  
         sem_post(&semaphore_liste_threads);  
 #       else  
         sem_post(semaphore_liste_threads);  
 #       endif  
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);          pthread_sigmask(SIG_SETMASK, &oldset, NULL);
         sigpending(&set);          sigpending(&set);
   
Line 136  insertion_thread(struct_processus *s_eta Line 108  insertion_thread(struct_processus *s_eta
     (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =      (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
             s_etat_processus;              s_etat_processus;
   
   #   ifndef SEMAPHORES_NOMMES
       while(sem_wait(&semaphore_liste_threads) == -1)
   #   else
       while(sem_wait(semaphore_liste_threads) == -1)
   #   endif
       {
           if (errno != EINTR)
           {
               pthread_sigmask(SIG_SETMASK, &oldset, NULL);
               sigpending(&set);
   
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
       }
   
       (*l_nouvel_objet).suivant = liste_threads;
   
     liste_threads = l_nouvel_objet;      liste_threads = l_nouvel_objet;
   
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
Line 168  insertion_thread_surveillance(struct_pro Line 158  insertion_thread_surveillance(struct_pro
     sigfillset(&set);      sigfillset(&set);
     pthread_sigmask(SIG_BLOCK, &set, &oldset);      pthread_sigmask(SIG_BLOCK, &set, &oldset);
   
       if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
               == NULL)
       {
           pthread_sigmask(SIG_SETMASK, &oldset, NULL);
           sigpending(&set);
   
           (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
           return;
       }
   
 #   ifndef SEMAPHORES_NOMMES  #   ifndef SEMAPHORES_NOMMES
     while(sem_wait(&semaphore_liste_threads) == -1)      while(sem_wait(&semaphore_liste_threads) == -1)
 #   else  #   else
Line 184  insertion_thread_surveillance(struct_pro Line 184  insertion_thread_surveillance(struct_pro
         }          }
     }      }
   
     if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))  printf("<1> +1 %d\n", (*s_argument_thread).nombre_references);
             == NULL)  
     {  
 #       ifndef SEMAPHORES_NOMMES  
         sem_post(&semaphore_liste_threads);  
 #       else  
         sem_post(semaphore_liste_threads);  
 #       endif  
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);  
         sigpending(&set);  
   
         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;  
         return;  
     }  
   
     (*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 289  retrait_thread(struct_processus *s_etat_ Line 275  retrait_thread(struct_processus *s_etat_
         (*l_element_precedent).suivant = (*l_element_courant).suivant;          (*l_element_precedent).suivant = (*l_element_courant).suivant;
     }      }
   
     free((void *) (*l_element_courant).donnee);  
     free((struct_liste_chainee_volatile *) l_element_courant);  
   
     if (pthread_setspecific(semaphore_fork_processus_courant, NULL) != 0)      if (pthread_setspecific(semaphore_fork_processus_courant, NULL) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
Line 319  retrait_thread(struct_processus *s_etat_ Line 302  retrait_thread(struct_processus *s_etat_
         return;          return;
     }      }
   
       free((void *) (*l_element_courant).donnee);
       free((struct_liste_chainee_volatile *) l_element_courant);
   
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);      pthread_sigmask(SIG_SETMASK, &oldset, NULL);
     sigpending(&set);      sigpending(&set);
     return;      return;
Line 390  retrait_thread_surveillance(struct_proce Line 376  retrait_thread_surveillance(struct_proce
         (*l_element_precedent).suivant = (*l_element_courant).suivant;          (*l_element_precedent).suivant = (*l_element_courant).suivant;
     }      }
   
     free((struct_liste_chainee_volatile *) l_element_courant);  
   
     if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)      if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
     {      {
   #       ifndef SEMAPHORES_NOMMES
           sem_post(&semaphore_liste_threads);
   #       else
           sem_post(semaphore_liste_threads);
   #       endif
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);          pthread_sigmask(SIG_SETMASK, &oldset, NULL);
         sigpending(&set);          sigpending(&set);
   
Line 402  retrait_thread_surveillance(struct_proce Line 391  retrait_thread_surveillance(struct_proce
     }      }
   
     (*s_argument_thread).nombre_references--;      (*s_argument_thread).nombre_references--;
   printf("<3> -1 %d %p\n", (*s_argument_thread).nombre_references, s_argument_thread);
   
     BUG((*s_argument_thread).nombre_references < 0,      BUG((*s_argument_thread).nombre_references < 0,
             printf("(*s_argument_thread).nombre_references = %d\n",              printf("(*s_argument_thread).nombre_references = %d\n",
             (int) (*s_argument_thread).nombre_references));              (int) (*s_argument_thread).nombre_references));
   
   printf("retrait_thread_surveillance : %d\n", (*s_argument_thread).nombre_references);
     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)) != 0)
         {          {
   #           ifndef SEMAPHORES_NOMMES
               sem_post(&semaphore_liste_threads);
   #           else
               sem_post(semaphore_liste_threads);
   #           endif
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);              pthread_sigmask(SIG_SETMASK, &oldset, NULL);
             sigpending(&set);              sigpending(&set);
   
Line 425  retrait_thread_surveillance(struct_proce Line 421  retrait_thread_surveillance(struct_proce
     {      {
         if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)          if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
         {          {
   #           ifndef SEMAPHORES_NOMMES
               sem_post(&semaphore_liste_threads);
   #           else
               sem_post(semaphore_liste_threads);
   #           endif
             pthread_sigmask(SIG_SETMASK, &oldset, NULL);              pthread_sigmask(SIG_SETMASK, &oldset, NULL);
             sigpending(&set);              sigpending(&set);
   
Line 446  retrait_thread_surveillance(struct_proce Line 447  retrait_thread_surveillance(struct_proce
         return;          return;
     }      }
   
       free((struct_liste_chainee_volatile *) l_element_courant);
   
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);      pthread_sigmask(SIG_SETMASK, &oldset, NULL);
     sigpending(&set);      sigpending(&set);
   
     return;      return;
 }  }
   
Line 626  liberation_threads(struct_processus *s_e Line 630  liberation_threads(struct_processus *s_e
             close((*s_etat_processus).pipe_nombre_objets_attente);              close((*s_etat_processus).pipe_nombre_objets_attente);
             close((*s_etat_processus).pipe_nombre_interruptions_attente);              close((*s_etat_processus).pipe_nombre_interruptions_attente);
   
               liberation(s_etat_processus, (*s_etat_processus).at_exit);
   
             if ((*s_etat_processus).nom_fichier_impression != NULL)              if ((*s_etat_processus).nom_fichier_impression != NULL)
             {              {
                 free((*s_etat_processus).nom_fichier_impression);                  free((*s_etat_processus).nom_fichier_impression);
Line 667  liberation_threads(struct_processus *s_e Line 673  liberation_threads(struct_processus *s_e
                     .l_base_pile_processus;                      .l_base_pile_processus;
             while(element_courant != NULL)              while(element_courant != NULL)
             {              {
                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)                  s_argument_thread = (struct_descripteur_thread *)
                         element_courant)).donnee).mutex));                          (*((struct_liste_chainee *) element_courant)).donnee;
                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)  
                         element_courant)).donnee).mutex));                  if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
                 liberation(s_etat_processus,                  {
                         (*((struct_liste_chainee *) element_courant)).donnee);                      (*s_etat_processus).erreur_systeme = d_es_processus;
                       sem_post(&semaphore_liste_threads);
                       return;
                   }
   
                   (*s_argument_thread).nombre_references--;
   printf("<1> -1 %d %p\n", (*s_argument_thread).nombre_references, s_argument_thread);
   
                   BUG((*s_argument_thread).nombre_references < 0,
                           printf("(*s_argument_thread).nombre_references = %d\n",
                           (int) (*s_argument_thread).nombre_references));
   
                   if ((*s_argument_thread).nombre_references == 0)
                   {
                       close((*s_argument_thread).pipe_objets[0]);
                       close((*s_argument_thread).pipe_acquittement[1]);
                       close((*s_argument_thread).pipe_injections[1]);
                       close((*s_argument_thread).pipe_nombre_injections[1]);
                       close((*s_argument_thread).pipe_nombre_objets_attente[0]);
                       close((*s_argument_thread).pipe_interruptions[0]);
                       close((*s_argument_thread)
                               .pipe_nombre_interruptions_attente[0]);
   
                       if (pthread_mutex_unlock(&((*s_argument_thread).mutex))
                               != 0)
                       {
                           (*s_etat_processus).erreur_systeme = d_es_processus;
                           sem_post(&semaphore_liste_threads);
                           return;
                       }
   
                       pthread_mutex_destroy(&((*s_argument_thread).mutex));
   
                       if ((*s_argument_thread).processus_detache == d_faux)
                       {
                           if ((*s_argument_thread).destruction_objet == d_vrai)
                           {
                               liberation(s_etat_processus, (*s_argument_thread)
                                       .argument);
                           }
                       }
   
                       free(s_argument_thread);
                   }
                   else
                   {
                       if (pthread_mutex_unlock(&((*s_argument_thread).mutex))
                               != 0)
                       {
                           (*s_etat_processus).erreur_systeme = d_es_processus;
                           sem_post(&semaphore_liste_threads);
                           return;
                       }
                   }
   
                 element_suivant = (*((struct_liste_chainee *) element_courant))                  element_suivant = (*((struct_liste_chainee *) element_courant))
                         .suivant;                          .suivant;
                 free((struct_liste_chainee *) element_courant);                  free(element_courant);
                 element_courant = element_suivant;                  element_courant = element_suivant;
             }              }
   
               (*s_etat_processus).l_base_pile_processus = NULL;
   
             pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));              pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
             pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));              pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
             liberation(s_etat_processus, (*s_etat_processus).indep);              liberation(s_etat_processus, (*s_etat_processus).indep);
Line 1153  liberation_threads(struct_processus *s_e Line 1215  liberation_threads(struct_processus *s_e
                 element_courant = element_suivant;                  element_courant = element_suivant;
             }              }
   
   /*
   ================================================================================
     À noter : on ne ferme pas la connexion car la conséquence immédiate est
     une destruction de l'objet pour le processus père.
   ================================================================================
   
             element_courant = (*s_etat_processus).s_connecteurs_sql;              element_courant = (*s_etat_processus).s_connecteurs_sql;
             while(element_courant != NULL)              while(element_courant != NULL)
             {              {
Line 1236  liberation_threads(struct_processus *s_e Line 1304  liberation_threads(struct_processus *s_e
   
                 element_courant = element_suivant;                  element_courant = element_suivant;
             }              }
   */
   
               (*s_etat_processus).s_connecteurs_sql = NULL;
   
             element_courant = (*s_etat_processus).s_marques;              element_courant = (*s_etat_processus).s_marques;
             while(element_courant != NULL)              while(element_courant != NULL)
Line 1280  liberation_threads(struct_processus *s_e Line 1351  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;
   
         close((*s_argument_thread).pipe_objets[0]);  
         close((*s_argument_thread).pipe_acquittement[1]);  
         close((*s_argument_thread).pipe_injections[1]);  
         close((*s_argument_thread).pipe_nombre_injections[1]);  
         close((*s_argument_thread).pipe_nombre_objets_attente[0]);  
         close((*s_argument_thread).pipe_interruptions[0]);  
         close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);  
   
         if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)          if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
         {          {
             (*s_etat_processus).erreur_systeme = d_es_processus;              (*s_etat_processus).erreur_systeme = d_es_processus;
               sem_post(&semaphore_liste_threads);
             return;              return;
         }          }
   
         (*s_argument_thread).nombre_references--;          (*s_argument_thread).nombre_references--;
   printf("<2> -1 %d %p\n", (*s_argument_thread).nombre_references, s_argument_thread);
   
         BUG((*s_argument_thread).nombre_references < 0,          BUG((*s_argument_thread).nombre_references < 0,
                 printf("(*s_argument_thread).nombre_references = %d\n",                  printf("(*s_argument_thread).nombre_references = %d\n",
Line 1302  liberation_threads(struct_processus *s_e Line 1367  liberation_threads(struct_processus *s_e
   
         if ((*s_argument_thread).nombre_references == 0)          if ((*s_argument_thread).nombre_references == 0)
         {          {
               close((*s_argument_thread).pipe_objets[0]);
               close((*s_argument_thread).pipe_acquittement[1]);
               close((*s_argument_thread).pipe_injections[1]);
               close((*s_argument_thread).pipe_nombre_injections[1]);
               close((*s_argument_thread).pipe_nombre_objets_attente[0]);
               close((*s_argument_thread).pipe_interruptions[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)) != 0)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                   sem_post(&semaphore_liste_threads);
                 return;                  return;
             }              }
   
             pthread_mutex_destroy(&((*s_argument_thread).mutex));              pthread_mutex_destroy(&((*s_argument_thread).mutex));
   
               if ((*s_argument_thread).processus_detache == d_faux)
               {
                   if ((*s_argument_thread).destruction_objet == d_vrai)
                   {
                       liberation(s_etat_processus, (*s_argument_thread).argument);
                   }
               }
   
             free(s_argument_thread);              free(s_argument_thread);
         }          }
         else          else
Line 1316  liberation_threads(struct_processus *s_e Line 1399  liberation_threads(struct_processus *s_e
             if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)              if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
                   sem_post(&semaphore_liste_threads);
                 return;                  return;
             }              }
         }          }
Line 1426  recherche_thread_principal(pid_t pid, pt Line 1510  recherche_thread_principal(pid_t pid, pt
 */  */
   
 // Les routines suivantes sont uniquement appelées depuis les gestionnaires  // Les routines suivantes sont uniquement appelées depuis les gestionnaires
 // des signaux asynchrones. Elles de doivent pas bloquer dans le cas où  // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
 // les sémaphores sont déjà bloqués par un gestionnaire de signal.  // les sémaphores sont déjà bloqués par un gestionnaire de signal.
   
 static inline void  static inline void
Line 1982  interruption5(int signal, siginfo_t *sig Line 2066  interruption5(int signal, siginfo_t *sig
     }      }
     else      else
     {      {
           if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
                   == NULL)
           {
               deverrouillage_gestionnaire_signaux();
               return;
           }
   
         // Envoi d'un signal au thread maître du groupe.          // Envoi d'un signal au thread maître du groupe.
   
         if (recherche_thread_principal(getpid(), &thread) == d_vrai)          if (recherche_thread_principal(getpid(), &thread) == d_vrai)
         {          {
             pthread_kill(thread, SIGFSTOP);              pthread_kill(thread, signal);
             deverrouillage_gestionnaire_signaux();              deverrouillage_gestionnaire_signaux();
             return;              return;
         }          }
Line 2110  interruption9(int signal, siginfo_t *sig Line 2201  interruption9(int signal, siginfo_t *sig
         fflush(stdout);          fflush(stdout);
     }      }
   
     pthread_kill((*s_etat_processus).tid_processus_pere, SIGFSTOP);  
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux();
       interruption11(signal, siginfo, context);
     return;      return;
 }  }
   
Line 2153  interruption10(int signal, siginfo_t *si Line 2244  interruption10(int signal, siginfo_t *si
     }      }
   
     deverrouillage_gestionnaire_signaux();      deverrouillage_gestionnaire_signaux();
       return;
   }
   
   void
   interruption11(int signal, siginfo_t *siginfo, void *context)
   {
       pthread_t               thread;
       struct_processus        *s_etat_processus;
   
       verrouillage_gestionnaire_signaux();
   
       if ((*siginfo).si_pid == getpid())
       {
           if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
                   == NULL)
           {
               deverrouillage_gestionnaire_signaux();
               return;
           }
   
           (*s_etat_processus).arret_depuis_abort = -1;
   
           if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
           {
               printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
                       (unsigned long long) pthread_self());
               fflush(stdout);
           }
   
           /*
            * var_globale_traitement_retarde_stop :
            *  0 -> traitement immédiat
            *  1 -> traitement retardé (aucun signal reçu)
            * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
            */
   
           if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
           {
               (*s_etat_processus).var_volatile_requete_arret = -1;
           }
           else
           {
               (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
           }
       }
       else
       {
           if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
                   == NULL)
           {
               deverrouillage_gestionnaire_signaux();
               return;
           }
   
           (*s_etat_processus).arret_depuis_abort = -1;
   
           // Envoi d'un signal au thread maître du groupe.
   
           if (recherche_thread_principal(getpid(), &thread) == d_vrai)
           {
               pthread_kill(thread, signal);
               deverrouillage_gestionnaire_signaux();
               return;
           }
       }
   
       deverrouillage_gestionnaire_signaux();
     return;      return;
 }  }
   

Removed from v.1.9  
changed lines
  Added in v.1.20


CVSweb interface <joel.bertrand@systella.fr>