Diff for /rpl/src/interruptions.c between versions 1.79 and 1.89

version 1.79, 2011/09/20 14:36:29 version 1.89, 2011/12/16 13:46:56
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.3    RPL/2 (R) version 4.1.5
   Copyright (C) 1989-2011 Dr. BERTRAND Joël    Copyright (C) 1989-2011 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
Line 1125  liberation_threads(struct_processus *s_e Line 1125  liberation_threads(struct_processus *s_e
                 sem_destroy(&((*s_etat_processus).semaphore_fork));                  sem_destroy(&((*s_etat_processus).semaphore_fork));
 #           else  #           else
                 sem_post((*s_etat_processus).semaphore_fork);                  sem_post((*s_etat_processus).semaphore_fork);
                 sem_destroy2((*s_etat_processus).semaphore_fork, getpid());                  sem_close((*s_etat_processus).semaphore_fork);
 #           endif  #           endif
   
             liberation_contexte_cas(s_etat_processus);              liberation_contexte_cas(s_etat_processus);
Line 1388  verrouillage_gestionnaire_signaux(struct Line 1388  verrouillage_gestionnaire_signaux(struct
   
         if (pthread_mutex_lock(&mutex_liste_threads) != 0)          if (pthread_mutex_lock(&mutex_liste_threads) != 0)
         {          {
   #           ifndef SEMAPHORES_NOMMES
             sem_wait(&((*s_etat_processus).semaphore_fork));              sem_wait(&((*s_etat_processus).semaphore_fork));
   #           else
               sem_wait((*s_etat_processus).semaphore_fork);
   #           endif
             BUG(1, uprintf("Lock error !\n"));              BUG(1, uprintf("Lock error !\n"));
             return;              return;
         }          }
Line 1506  interruption1(int signal) Line 1510  interruption1(int signal)
             envoi_signal_processus(getpid(), rpl_sigterm);              envoi_signal_processus(getpid(), rpl_sigterm);
             break;              break;
   
         case SIGALRM:          case SIGUSR1:
             envoi_signal_processus(getpid(), rpl_sigalrm);              envoi_signal_processus(getpid(), rpl_sigalrm);
             break;              break;
     }      }
Line 1756  interruption3(int signal) Line 1760  interruption3(int signal)
     // l'erreur d'accès à la mémoire. On sort donc du programme quitte à      // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
     // ce qu'il reste des processus orphelins.      // ce qu'il reste des processus orphelins.
   
     unsigned char       message[] = "+++System : Uncaught access violation\n"      unsigned char       message_1[] = "+++System : Uncaught access violation\n"
                                   "+++System : Aborting !\n";
       unsigned char       message_2[] = "+++System : Stack overflow\n"
                                 "+++System : Aborting !\n";                                  "+++System : Aborting !\n";
   
     test_signal(signal);      test_signal(signal);
   
     if (pid_processus_pere == getpid())      if (pid_processus_pere == getpid())
     {      {
         kill(pid_processus_pere, SIGALRM);          kill(pid_processus_pere, SIGUSR1);
       }
   
       if (signal != SIGUSR2)
       {
           write(STDERR_FILENO, message_1, strlen(message_1));
       }
       else
       {
           write(STDERR_FILENO, message_2, strlen(message_2));
     }      }
   
     write(STDERR_FILENO, message, strlen(message));  
     _exit(EXIT_FAILURE);      _exit(EXIT_FAILURE);
 }  }
   
 #if 0  
 // Utiliser libsigsegv  static void
 void INTERRUPTION3_A_FIXER()  sortie_interruption_depassement_pile(void *arg1, void *arg2, void *arg3)
 {  {
     pthread_t               thread;      switch((*((volatile int *) arg1)))
       {
           case 1:
               longjmp(contexte_ecriture, -1);
               break;
   
     struct_processus        *s_etat_processus;          case 2:
               longjmp(contexte_impression, -1);
               break;
       }
   
     test_signal(signal);      return;
     verrouillage_gestionnaire_signaux(s_etat_processus);  }
   
     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)  void
   interruption_depassement_pile(int urgence, stackoverflow_context_t scp)
   {
       if ((urgence == 0) && (routine_recursive != 0))
     {      {
         printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),          // On peut tenter de récupérer le dépassement de pile. Si la variable
                 (unsigned long long) pthread_self());          // 'routine_recursive' est non nulle, on récupère l'erreur.
         fflush(stdout);  
     }  
   
     if ((*s_etat_processus).var_volatile_recursivite == -1)          sigsegv_leave_handler(sortie_interruption_depassement_pile,
     {                  (void *) &routine_recursive, NULL, NULL);
         // Segfault dans un appel de fonction récursive  
         deverrouillage_gestionnaire_signaux(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)  
         {  
             // 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)  int
             {  interruption_violation_access(void *adresse_fautive, int gravite)
                 printf("+++Système : Violation d'accès, tentative de "  {
                         "terminaison de la tâche\n");      unsigned char       message[] = "+++System : Trying to catch access "
                 printf("             (defauts multiples)\n");                                  "violation\n";
             }  
             else  
             {  
                 printf("+++System : Access violation, trying to kill task "  
                         "(multiple defaults)\n");  
             }  
   
             fflush(stdout);      static int          compteur_erreur = 0;
   
             deverrouillage_gestionnaire_signaux(s_etat_processus);      if ((gravite == 0) && (routine_recursive != 0))
             exit(EXIT_FAILURE);      {
         }          // Il peut s'agir d'un dépassement de pile.
         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(s_etat_processus);  
   
                     if ((*s_etat_processus).pid_processus_pere != getpid())          sigsegv_leave_handler(sortie_interruption_depassement_pile,
                     {                  (void *) &routine_recursive, NULL, NULL);
                         // On est dans le thread principal d'un processus.      }
   
                         longjmp(contexte_processus, -1);      // On est dans une bonne vieille violation d'accès. On essaie
                     }      // de fermer au mieux l'application.
                     else  
                     {  
                         // On est dans le thread principal du processus  
                         // père.  
   
                         longjmp(contexte_initial, -1);      compteur_erreur++;
                     }  
                 }  
                 else  
                 {  
                     // On est dans un thread fils d'un thread principal.  
   
                     deverrouillage_gestionnaire_signaux(s_etat_processus);      if (compteur_erreur >= 2)
                     longjmp(contexte_thread, -1);      {
                 }          // Erreurs multiples, on arrête l'application.
             }          interruption3(SIGSEGV);
           return(0);
       }
   
             // Là, on ramasse les miettes puisque le thread n'existe plus      write(STDERR_FILENO, message, strlen(message));
             // 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 1955  signal_stop(struct_processus *s_etat_pro Line 1934  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 2053  signal_urg(struct_processus *s_etat_proc Line 2025  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 2109  signal_abort(struct_processus *s_etat_pr Line 2074  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 2429  nom_segment(unsigned char *chemin, pid_t Line 2387  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  #       ifdef SEMAPHORES_NOMMES
             sem_t                   *semaphore;              sem_t                   *semaphore;
 #       endif  #       endif
 #   else  #   else
         int                         desc;  #       ifndef OS2
         key_t                       clef;              int                     desc;
               key_t                   clef;
   #       endif
 #   endif  #   endif
   
     struct_queue_signaux            *queue;      struct_queue_signaux            *queue;
Line 2496  envoi_signal_processus(pid_t pid, enum s Line 2458  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);                      free(nom);
             }                      return(1);
                   }
   
             close(desc);                  close(desc);
   
                   if ((clef = ftok(nom, 1)) == -1)
                   {
                       free(nom);
                       return(1);
                   }
   
             if ((clef = ftok(nom, 1)) == -1)  
             {  
                 free(nom);                  free(nom);
                 return(1);  
             }  
   
             free(nom);                  if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0))
                           == -1)
                   {
                       return(1);
                   }
   
             if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0)) == -1)                  queue = shmat(segment, NULL, 0);
             {  #           else // OS/2
                 return(1);                  if (DosGetNamedSharedMem((PVOID) &queue, nom,
             }                          PAG_WRITE | PAG_READ) != 0)
                   {
                       free(nom);
                       return(1);
                   }
   
             queue = shmat(segment, NULL, 0);                  free(nom);
   #           endif
 #       else // POSIX  #       else // POSIX
             if ((nom = nom_segment(racine_segment, pid)) == NULL)              if ((nom = nom_segment(racine_segment, pid)) == NULL)
             {              {
Line 2554  envoi_signal_processus(pid_t pid, enum s Line 2528  envoi_signal_processus(pid_t pid, enum s
                     }                      }
                 }                  }
 #           else  #           else
                 if ((semaphore = sem_open2(pid)) == SEM_FAILED)                  if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)
                 {                  {
                     return(1);                      return(1);
                 }                  }
Line 2614  envoi_signal_processus(pid_t pid, enum s Line 2588  envoi_signal_processus(pid_t pid, enum s
                 return(1);                  return(1);
             }              }
   
             if (shmdt(queue) != 0)  #           ifndef OS2 // SysV
             {                  if (shmdt(queue) != 0)
                 return(1);                  {
             }                      return(1);
                   }
   #           else // OS/2
                   // Pendant de DosGetNamedSHaredMem()
   #           endif
 #       endif  #       endif
     }      }
   
       kill(pid, SIGALRM);
   
     return(0);      return(0);
 }  }
   
Line 2684  envoi_signal_thread(pthread_t tid, enum Line 2664  envoi_signal_thread(pthread_t tid, enum
         return(1);          return(1);
     }      }
   
       pthread_kill(tid, SIGALRM);
   
     return(0);      return(0);
 }  }
   
Line 2700  envoi_signal_contexte(struct_processus * Line 2682  envoi_signal_contexte(struct_processus *
             % LONGUEUR_QUEUE_SIGNAUX;              % LONGUEUR_QUEUE_SIGNAUX;
     pthread_mutex_unlock(&mutex_interruptions);      pthread_mutex_unlock(&mutex_interruptions);
   
       pthread_kill((*s_etat_processus_a_signaler).tid, SIGALRM);
   
     return(0);      return(0);
 }  }
   
Line 2769  creation_queue_signaux(struct_processus Line 2753  creation_queue_signaux(struct_processus
 #       ifndef SEMAPHORES_NOMMES  #       ifndef SEMAPHORES_NOMMES
             sem_init(&((*s_queue_signaux).semaphore), 1, 1);              sem_init(&((*s_queue_signaux).semaphore), 1, 1);
 #       else  #       else
             if ((semaphore_queue_signaux = sem_init2(1, getpid()))              if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
                     == SEM_FAILED)                      == SEM_FAILED)
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  (*s_etat_processus).erreur_systeme = d_es_processus;
Line 2851  creation_queue_signaux(struct_processus Line 2835  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);                  free(nom);
Line 2861  creation_queue_signaux(struct_processus Line 2845  creation_queue_signaux(struct_processus
             }              }
   
             free(nom);              free(nom);
             fifos = ptr_os2;  
               sem_init(&((*s_queue_signaux).semaphore), 1, 1);
               (*s_queue_signaux).pointeur_lecture = 0;
               (*s_queue_signaux).pointeur_ecriture = 0;
 #       endif  #       endif
 #   endif  #   endif
   
Line 2930  liberation_queue_signaux(struct_processu Line 2917  liberation_queue_signaux(struct_processu
 void  void
 destruction_queue_signaux(struct_processus *s_etat_processus)  destruction_queue_signaux(struct_processus *s_etat_processus)
 {  {
     unsigned char       *nom;  #   ifndef OS2
           unsigned char       *nom;
   #   endif
   
 #   ifdef IPCS_SYSV // SystemV  #   ifdef IPCS_SYSV // SystemV
 #       ifndef OS2  #       ifndef OS2
Line 2966  destruction_queue_signaux(struct_process Line 2955  destruction_queue_signaux(struct_process
             unlink(nom);              unlink(nom);
             free(nom);              free(nom);
 #       else  #       else
             if (DosFreeMem(fifos) != 0)              sem_close(&((*s_queue_signaux).semaphore));
               sem_destroy(&((*s_queue_signaux).semaphore));
   
               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  #       ifndef SEMAPHORES_NOMMES
Line 2981  destruction_queue_signaux(struct_process Line 2970  destruction_queue_signaux(struct_process
             sem_destroy(&((*s_queue_signaux).semaphore));              sem_destroy(&((*s_queue_signaux).semaphore));
 #       else  #       else
             sem_close(semaphore_queue_signaux);              sem_close(semaphore_queue_signaux);
             sem_destroy2(semaphore_queue_signaux, getpid());              sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);
 #       endif  #       endif
   
         if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)          if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)

Removed from v.1.79  
changed lines
  Added in v.1.89


CVSweb interface <joel.bertrand@systella.fr>