File:  [local] / rpl / src / interruptions.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Jan 26 15:22:44 2010 UTC (14 years, 3 months ago) by bertrand
Branches: JKB
CVS tags: start


Commit initial.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.0.9
    4:   Copyright (C) 1989-2010 Dr. BERTRAND Joël
    5: 
    6:   This file is part of RPL/2.
    7: 
    8:   RPL/2 is free software; you can redistribute it and/or modify it
    9:   under the terms of the CeCILL V2 License as published by the french
   10:   CEA, CNRS and INRIA.
   11:  
   12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
   13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
   15:   for more details.
   16:  
   17:   You should have received a copy of the CeCILL License
   18:   along with RPL/2. If not, write to info@cecill.info.
   19: ================================================================================
   20: */
   21: 
   22: 
   23: #include "rpl.conv.h"
   24: 
   25: 
   26: /*
   27: ================================================================================
   28:   Procédures de gestion par thread des variables issues des gestionnaires
   29:   de signaux
   30: ================================================================================
   31:   Entrée : variable globale
   32: --------------------------------------------------------------------------------
   33:   Sortie : variable globale modifiée
   34: --------------------------------------------------------------------------------
   35:   Effets de bord : néant
   36: ================================================================================
   37: */
   38: 
   39: typedef struct thread
   40: {
   41:     pid_t               pid;
   42:     pthread_t           tid;
   43: 
   44:     logical1            thread_principal;
   45: 
   46:     struct_processus    *s_etat_processus;
   47: } struct_thread;
   48: 
   49: typedef struct liste_chainee_volatile
   50: {
   51:     volatile struct liste_chainee_volatile  *suivant;
   52:     volatile void                           *donnee;
   53: } struct_liste_chainee_volatile;
   54: 
   55: 
   56: static volatile struct_liste_chainee_volatile   *liste_threads
   57:         = NULL;
   58: static volatile struct_liste_chainee_volatile   *liste_threads_surveillance
   59:         = NULL;
   60: 
   61: void
   62: modification_pid_thread_pere(struct_processus *s_etat_processus)
   63: {
   64:     // La variable existe toujours et aucun thread concurrent ne peut
   65:     // la modifier puisque cette routine ne peut être appelée que depuis
   66:     // DAEMON.
   67: 
   68:     (*((struct_thread *) (*liste_threads).donnee)).pid =
   69:             (*s_etat_processus).pid_processus_pere;
   70: 
   71:     return;
   72: }
   73: 
   74: void
   75: insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)
   76: {
   77:     sigset_t                                    oldset;
   78:     sigset_t                                    set;
   79: 
   80:     volatile struct_liste_chainee_volatile      *l_nouvel_objet;
   81: 
   82:     sigfillset(&set);
   83:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
   84: 
   85:     while(sem_wait(&semaphore_liste_threads) == -1)
   86:     {
   87:         if (errno != EINTR)
   88:         {
   89:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
   90:             sigpending(&set);
   91: 
   92:             (*s_etat_processus).erreur_systeme = d_es_processus;
   93:             return;
   94:         }
   95:     }
   96: 
   97:     if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
   98:             == NULL)
   99:     {
  100:         sem_post(&semaphore_liste_threads);
  101:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  102:         sigpending(&set);
  103: 
  104:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  105:         return;
  106:     }
  107: 
  108:     (*l_nouvel_objet).suivant = liste_threads;
  109: 
  110:     if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)
  111:     {
  112:         sem_post(&semaphore_liste_threads);
  113:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  114:         sigpending(&set);
  115: 
  116:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  117:         return;
  118:     }
  119: 
  120:     (*((struct_thread *) (*l_nouvel_objet).donnee)).pid = getpid();
  121:     (*((struct_thread *) (*l_nouvel_objet).donnee)).tid = pthread_self();
  122:     (*((struct_thread *) (*l_nouvel_objet).donnee)).thread_principal =
  123:             thread_principal;
  124:     (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
  125:             s_etat_processus;
  126: 
  127:     liste_threads = l_nouvel_objet;
  128: 
  129:     if (sem_post(&semaphore_liste_threads) != 0)
  130:     {
  131:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  132:         sigpending(&set);
  133: 
  134:         (*s_etat_processus).erreur_systeme = d_es_processus;
  135:         return;
  136:     }
  137: 
  138:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  139:     sigpending(&set);
  140:     return;
  141: }
  142: 
  143: void
  144: insertion_thread_surveillance(struct_processus *s_etat_processus,
  145:         struct_descripteur_thread *s_argument_thread)
  146: {
  147:     sigset_t                                    oldset;
  148:     sigset_t                                    set;
  149: 
  150:     volatile struct_liste_chainee_volatile      *l_nouvel_objet;
  151: 
  152:     sigfillset(&set);
  153:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
  154: 
  155:     while(sem_wait(&semaphore_liste_threads) == -1)
  156:     {
  157:         if (errno != EINTR)
  158:         {
  159:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  160:             sigpending(&set);
  161: 
  162:             (*s_etat_processus).erreur_systeme = d_es_processus;
  163:             return;
  164:         }
  165:     }
  166: 
  167:     if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
  168:             == NULL)
  169:     {
  170:         sem_post(&semaphore_liste_threads);
  171:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  172:         sigpending(&set);
  173: 
  174:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  175:         return;
  176:     }
  177: 
  178:     (*l_nouvel_objet).suivant = liste_threads_surveillance;
  179:     (*l_nouvel_objet).donnee = (void *) s_argument_thread;
  180: 
  181:     liste_threads_surveillance = l_nouvel_objet;
  182: 
  183:     if (sem_post(&semaphore_liste_threads) != 0)
  184:     {
  185:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  186:         sigpending(&set);
  187: 
  188:         (*s_etat_processus).erreur_systeme = d_es_processus;
  189:         return;
  190:     }
  191: 
  192:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  193:     sigpending(&set);
  194:     return;
  195: }
  196: 
  197: void
  198: retrait_thread(struct_processus *s_etat_processus)
  199: {
  200:     sigset_t                                oldset;
  201:     sigset_t                                set;
  202: 
  203:     volatile struct_liste_chainee_volatile  *l_element_precedent;
  204:     volatile struct_liste_chainee_volatile  *l_element_courant;
  205: 
  206:     sigfillset(&set);
  207:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
  208: 
  209:     while(sem_wait(&semaphore_liste_threads) == -1)
  210:     {
  211:         if (errno != EINTR)
  212:         {
  213:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  214:             sigpending(&set);
  215: 
  216:             (*s_etat_processus).erreur_systeme = d_es_processus;
  217:             return;
  218:         }
  219:     }
  220: 
  221:     l_element_precedent = NULL;
  222:     l_element_courant = liste_threads;
  223: 
  224:     while(l_element_courant != NULL)
  225:     {
  226:         if (((*((struct_thread *) (*l_element_courant).donnee)).pid
  227:                 == getpid()) && (pthread_equal((*((struct_thread *)
  228:                 (*l_element_courant).donnee)).tid, pthread_self()) != 0))
  229:         {
  230:             break;
  231:         }
  232: 
  233:         l_element_precedent = l_element_courant;
  234:         l_element_courant = (*l_element_courant).suivant;
  235:     }
  236: 
  237:     if (l_element_courant == NULL)
  238:     {
  239:         sem_post(&semaphore_liste_threads);
  240:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  241:         sigpending(&set);
  242: 
  243:         (*s_etat_processus).erreur_systeme = d_es_processus;
  244:         return;
  245:     }
  246: 
  247:     if (l_element_precedent == NULL)
  248:     {
  249:         liste_threads = (*l_element_courant).suivant;
  250:     }
  251:     else
  252:     {
  253:         (*l_element_precedent).suivant = (*l_element_courant).suivant;
  254:     }
  255: 
  256:     free((void *) (*l_element_courant).donnee);
  257:     free((struct_liste_chainee_volatile *) l_element_courant);
  258: 
  259:     if (pthread_setspecific(semaphore_fork_processus_courant, NULL) != 0)
  260:     {
  261:         (*s_etat_processus).erreur_systeme = d_es_processus;
  262: 
  263:         sem_post(&semaphore_liste_threads);
  264:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  265:         sigpending(&set);
  266:         return;
  267:     }
  268: 
  269:     if (sem_post(&semaphore_liste_threads) != 0)
  270:     {
  271:         (*s_etat_processus).erreur_systeme = d_es_processus;
  272: 
  273:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  274:         sigpending(&set);
  275:         return;
  276:     }
  277: 
  278:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  279:     sigpending(&set);
  280:     return;
  281: }
  282: 
  283: void
  284: retrait_thread_surveillance(struct_processus *s_etat_processus,
  285:         struct_descripteur_thread *s_argument_thread)
  286: {
  287:     sigset_t                                set;
  288:     sigset_t                                oldset;
  289: 
  290:     volatile struct_liste_chainee_volatile  *l_element_precedent;
  291:     volatile struct_liste_chainee_volatile  *l_element_courant;
  292: 
  293:     sigfillset(&set);
  294:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
  295: 
  296:     while(sem_wait(&semaphore_liste_threads) == -1)
  297:     {
  298:         if (errno != EINTR)
  299:         {
  300:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  301:             sigpending(&set);
  302: 
  303:             (*s_etat_processus).erreur_systeme = d_es_processus;
  304:             return;
  305:         }
  306:     }
  307: 
  308:     l_element_precedent = NULL;
  309:     l_element_courant = liste_threads_surveillance;
  310: 
  311:     while(l_element_courant != NULL)
  312:     {
  313:         if ((*l_element_courant).donnee == (void *) s_argument_thread)
  314:         {
  315:             break;
  316:         }
  317: 
  318:         l_element_precedent = l_element_courant;
  319:         l_element_courant = (*l_element_courant).suivant;
  320:     }
  321: 
  322:     if (l_element_courant == NULL)
  323:     {
  324:         sem_post(&semaphore_liste_threads);
  325:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  326:         sigpending(&set);
  327: 
  328:         (*s_etat_processus).erreur_systeme = d_es_processus;
  329:         return;
  330:     }
  331: 
  332:     if (l_element_precedent == NULL)
  333:     {
  334:         liste_threads_surveillance = (*l_element_courant).suivant;
  335:     }
  336:     else
  337:     {
  338:         (*l_element_precedent).suivant = (*l_element_courant).suivant;
  339:     }
  340: 
  341:     free((struct_liste_chainee_volatile *) l_element_courant);
  342: 
  343:     if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
  344:     {
  345:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  346:         sigpending(&set);
  347: 
  348:         (*s_etat_processus).erreur_systeme = d_es_processus;
  349:         return;
  350:     }
  351: 
  352:     (*s_argument_thread).nombre_references--;
  353: 
  354:     BUG((*s_argument_thread).nombre_references < 0,
  355:             printf("(*s_argument_thread).nombre_references = %d\n",
  356:             (int) (*s_argument_thread).nombre_references));
  357: 
  358:     if ((*s_argument_thread).nombre_references == 0)
  359:     {
  360:         if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
  361:         {
  362:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  363:             sigpending(&set);
  364: 
  365:             (*s_etat_processus).erreur_systeme = d_es_processus;
  366:             return;
  367:         }
  368: 
  369:         pthread_mutex_destroy(&((*s_argument_thread).mutex));
  370:         free(s_argument_thread);
  371:     }
  372:     else
  373:     {
  374:         if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
  375:         {
  376:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  377:             sigpending(&set);
  378: 
  379:             (*s_etat_processus).erreur_systeme = d_es_processus;
  380:             return;
  381:         }
  382:     }
  383: 
  384:     if (sem_post(&semaphore_liste_threads) != 0)
  385:     {
  386:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  387:         sigpending(&set);
  388: 
  389:         (*s_etat_processus).erreur_systeme = d_es_processus;
  390:         return;
  391:     }
  392: 
  393:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  394:     sigpending(&set);
  395:     return;
  396: }
  397: 
  398: void
  399: verrouillage_threads_concurrents(struct_processus *s_etat_processus)
  400: {
  401:     volatile struct_liste_chainee_volatile  *l_element_courant;
  402: 
  403:     while(sem_wait(&semaphore_liste_threads) == -1)
  404:     {
  405:         if (errno != EINTR)
  406:         {
  407:             (*s_etat_processus).erreur_systeme = d_es_processus;
  408:             return;
  409:         }
  410:     }
  411: 
  412:     l_element_courant = liste_threads;
  413: 
  414:     while(l_element_courant != NULL)
  415:     {
  416:         if (((*((struct_thread *) (*l_element_courant).donnee)).pid
  417:                 == getpid()) && (pthread_equal((*((struct_thread *)
  418:                 (*l_element_courant).donnee)).tid, pthread_self()) == 0))
  419:         {
  420:             while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)
  421:                     .donnee)).s_etat_processus).semaphore_fork)) == -1)
  422:             {
  423:                 if (errno != EINTR)
  424:                 {
  425:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  426:                     return;
  427:                 }
  428:             }
  429:         }
  430: 
  431:         l_element_courant = (*l_element_courant).suivant;
  432:     }
  433: 
  434:     return;
  435: }
  436: 
  437: void
  438: deverrouillage_threads_concurrents(struct_processus *s_etat_processus)
  439: {
  440:     volatile struct_liste_chainee_volatile  *l_element_courant;
  441: 
  442:     l_element_courant = liste_threads;
  443: 
  444:     while(l_element_courant != NULL)
  445:     {
  446:         if (((*((struct_thread *) (*l_element_courant).donnee)).pid
  447:                 == getpid()) && (pthread_equal((*((struct_thread *)
  448:                 (*l_element_courant).donnee)).tid, pthread_self()) == 0))
  449:         {
  450:             if (sem_post(&((*(*((struct_thread *)
  451:                     (*l_element_courant).donnee)).s_etat_processus)
  452:                     .semaphore_fork)) != 0)
  453:             {
  454:                 if (sem_post(&semaphore_liste_threads) != 0)
  455:                 {
  456:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  457:                     return;
  458:                 }
  459: 
  460:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  461:                 return;
  462:             }
  463:         }
  464: 
  465:         l_element_courant = (*l_element_courant).suivant;
  466:     }
  467: 
  468:     if (sem_post(&semaphore_liste_threads) != 0)
  469:     {
  470:         (*s_etat_processus).erreur_systeme = d_es_processus;
  471:         return;
  472:     }
  473: 
  474:     return;
  475: }
  476: 
  477: void
  478: liberation_threads(struct_processus *s_etat_processus)
  479: {
  480:     logical1                                    suppression_variables_partagees;
  481: 
  482:     sigset_t                                    oldset;
  483:     sigset_t                                    set;
  484: 
  485:     struct_descripteur_thread                   *s_argument_thread;
  486: 
  487:     struct_processus                            *candidat;
  488: 
  489:     unsigned long                               i;
  490: 
  491:     void                                        *element_candidat;
  492:     void                                        *element_courant;
  493:     void                                        *element_suivant;
  494: 
  495:     volatile struct_liste_chainee_volatile      *l_element_courant;
  496:     volatile struct_liste_chainee_volatile      *l_element_suivant;
  497: 
  498:     sigfillset(&set);
  499:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
  500: 
  501:     while(sem_wait(&semaphore_liste_threads) == -1)
  502:     {
  503:         if (errno != EINTR)
  504:         {
  505:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  506:             (*s_etat_processus).erreur_systeme = d_es_processus;
  507:             return;
  508:         }
  509:     }
  510: 
  511:     l_element_courant = liste_threads;
  512:     suppression_variables_partagees = d_faux;
  513: 
  514:     while(l_element_courant != NULL)
  515:     {
  516:         if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus
  517:                 != s_etat_processus)
  518:         {
  519:             candidat = s_etat_processus;
  520:             s_etat_processus = (*((struct_thread *)
  521:                     (*l_element_courant).donnee)).s_etat_processus;
  522:             free((*s_etat_processus).localisation);
  523: 
  524:             // (*s_etat_processus).instruction_courante peut pointer sur
  525:             // n'importe quoi (une instruction courante ou un champ d'une
  526:             // structure objet). On ne le libère pas quitte à avoir une
  527:             // petite fuite mémoire dans le processus fils.
  528: 
  529:             if ((*s_etat_processus).instruction_courante != NULL)
  530:             {
  531:                 //free((*s_etat_processus).instruction_courante);
  532:             }
  533: 
  534:             close((*s_etat_processus).pipe_acquittement);
  535:             close((*s_etat_processus).pipe_donnees);
  536:             close((*s_etat_processus).pipe_injections);
  537:             close((*s_etat_processus).pipe_nombre_injections);
  538:             close((*s_etat_processus).pipe_interruptions);
  539:             close((*s_etat_processus).pipe_nombre_objets_attente);
  540:             close((*s_etat_processus).pipe_nombre_interruptions_attente);
  541: 
  542:             if ((*s_etat_processus).nom_fichier_impression != NULL)
  543:             {
  544:                 free((*s_etat_processus).nom_fichier_impression);
  545:             }
  546: 
  547:             while((*s_etat_processus).fichiers_graphiques != NULL)
  548:             {
  549:                 free((*(*s_etat_processus).fichiers_graphiques).nom);
  550: 
  551:                 if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
  552:                 {
  553:                     free((*(*s_etat_processus).fichiers_graphiques).legende);
  554:                 }
  555: 
  556:                 element_courant = (*s_etat_processus).fichiers_graphiques;
  557:                 (*s_etat_processus).fichiers_graphiques =
  558:                         (*(*s_etat_processus).fichiers_graphiques).suivant;
  559: 
  560:                 free(element_courant);
  561:             }
  562: 
  563:             if ((*s_etat_processus).entree_standard != NULL)
  564:             {
  565:                 pclose((*s_etat_processus).entree_standard);
  566:             }
  567: 
  568:             if ((*s_etat_processus).generateur_aleatoire != NULL)
  569:             {
  570:                 liberation_generateur_aleatoire(s_etat_processus);
  571:             }
  572: 
  573:             if ((*s_etat_processus).instruction_derniere_erreur != NULL)
  574:             {
  575:                 free((*s_etat_processus).instruction_derniere_erreur);
  576:                 (*s_etat_processus).instruction_derniere_erreur = NULL;
  577:             }
  578: 
  579:             element_courant = (void *) (*s_etat_processus)
  580:                     .l_base_pile_processus;
  581:             while(element_courant != NULL)
  582:             {
  583:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  584:                         element_courant)).donnee).mutex));
  585:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  586:                         element_courant)).donnee).mutex));
  587:                 liberation(s_etat_processus,
  588:                         (*((struct_liste_chainee *) element_courant)).donnee);
  589:                 element_suivant = (*((struct_liste_chainee *) element_courant))
  590:                         .suivant;
  591:                 free((struct_liste_chainee *) element_courant);
  592:                 element_courant = element_suivant;
  593:             }
  594: 
  595:             pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
  596:             pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
  597:             liberation(s_etat_processus, (*s_etat_processus).indep);
  598: 
  599:             pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex));
  600:             pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex));
  601:             liberation(s_etat_processus, (*s_etat_processus).depend);
  602: 
  603:             free((*s_etat_processus).label_x);
  604:             free((*s_etat_processus).label_y);
  605:             free((*s_etat_processus).label_z);
  606:             free((*s_etat_processus).titre);
  607:             free((*s_etat_processus).legende);
  608: 
  609:             pthread_mutex_trylock(&((*(*s_etat_processus)
  610:                     .parametres_courbes_de_niveau).mutex));
  611:             pthread_mutex_unlock(&((*(*s_etat_processus)
  612:                     .parametres_courbes_de_niveau).mutex));
  613:             liberation(s_etat_processus, (*s_etat_processus)
  614:                     .parametres_courbes_de_niveau);
  615: 
  616:             for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
  617:             {
  618:                 if ((*s_etat_processus).corps_interruptions[i] != NULL)
  619:                 {
  620:                     pthread_mutex_trylock(&((*(*s_etat_processus)
  621:                             .corps_interruptions[i]).mutex));
  622:                     pthread_mutex_unlock(&((*(*s_etat_processus)
  623:                             .corps_interruptions[i]).mutex));
  624: 
  625:                     liberation(s_etat_processus,
  626:                             (*s_etat_processus).corps_interruptions[i]);
  627:                 }
  628: 
  629:                 element_courant = (*s_etat_processus)
  630:                         .pile_origine_interruptions[i];
  631: 
  632:                 while(element_courant != NULL)
  633:                 {
  634:                     element_suivant = (*((struct_liste_chainee *)
  635:                             element_courant)).suivant;
  636: 
  637:                     pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  638:                             element_courant)).donnee).mutex));
  639:                     pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  640:                             element_courant)).donnee).mutex));
  641: 
  642:                     liberation(s_etat_processus,
  643:                             (*((struct_liste_chainee *) element_courant))
  644:                             .donnee);
  645:                     free(element_courant);
  646: 
  647:                     element_courant = element_suivant;
  648:                 }
  649:             }
  650: 
  651:             for(i = 0; i < (*s_etat_processus).nombre_variables; i++)
  652:             {
  653:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  654:                         .s_liste_variables[i].objet).mutex));
  655:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  656:                         .s_liste_variables[i].objet).mutex));
  657: 
  658:                 // Les variables de niveau 0 sont des définitions qui
  659:                 // ne sont pas copiées entre threads.
  660:                 if ((*s_etat_processus).s_liste_variables[i].niveau > 0)
  661:                 {
  662:                     liberation(s_etat_processus,
  663:                             (*s_etat_processus).s_liste_variables[i].objet);
  664:                 }
  665: 
  666:                 free((*s_etat_processus).s_liste_variables[i].nom);
  667:             }
  668: 
  669:             free((*s_etat_processus).s_liste_variables);
  670: 
  671:             for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
  672:             {
  673:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  674:                         .s_liste_variables_statiques[i].objet).mutex));
  675:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  676:                         .s_liste_variables_statiques[i].objet).mutex));
  677: 
  678:                 liberation(s_etat_processus, (*s_etat_processus)
  679:                         .s_liste_variables_statiques[i].objet);
  680:                 free((*s_etat_processus).s_liste_variables_statiques[i].nom);
  681:             }
  682: 
  683:             free((*s_etat_processus).s_liste_variables_statiques);
  684: 
  685:             // Ne peut être effacé qu'une seule fois
  686:             if (suppression_variables_partagees == d_faux)
  687:             {
  688:                 suppression_variables_partagees = d_vrai;
  689: 
  690:                 for(i = 0; i < (*(*s_etat_processus)
  691:                         .s_liste_variables_partagees).nombre_variables; i++)
  692:                 {
  693:                     pthread_mutex_trylock(&((*(*(*s_etat_processus)
  694:                             .s_liste_variables_partagees).table[i].objet)
  695:                             .mutex));
  696:                     pthread_mutex_unlock(&((*(*(*s_etat_processus)
  697:                             .s_liste_variables_partagees).table[i].objet)
  698:                             .mutex));
  699: 
  700:                     liberation(s_etat_processus, (*(*s_etat_processus)
  701:                             .s_liste_variables_partagees).table[i].objet);
  702:                     free((*(*s_etat_processus).s_liste_variables_partagees)
  703:                             .table[i].nom);
  704:                 }
  705: 
  706:                 if ((*(*s_etat_processus).s_liste_variables_partagees).table
  707:                         != NULL)
  708:                 {
  709:                     free((struct_variable_partagee *) (*(*s_etat_processus)
  710:                             .s_liste_variables_partagees).table);
  711:                 }
  712: 
  713:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  714:                         .s_liste_variables_partagees).mutex));
  715:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  716:                         .s_liste_variables_partagees).mutex));
  717:             }
  718: 
  719:             element_courant = (*s_etat_processus).l_base_pile;
  720:             while(element_courant != NULL)
  721:             {
  722:                 element_suivant = (*((struct_liste_chainee *)
  723:                         element_courant)).suivant;
  724: 
  725:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  726:                         element_courant)).donnee).mutex));
  727:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  728:                         element_courant)).donnee).mutex));
  729: 
  730:                 liberation(s_etat_processus,
  731:                         (*((struct_liste_chainee *)
  732:                         element_courant)).donnee);
  733:                 free((struct_liste_chainee *) element_courant);
  734: 
  735:                 element_courant = element_suivant;
  736:             }
  737: 
  738:             element_courant = (*s_etat_processus).l_base_pile_contextes;
  739:             while(element_courant != NULL)
  740:             {
  741:                 element_suivant = (*((struct_liste_chainee *)
  742:                         element_courant)).suivant;
  743: 
  744:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  745:                         element_courant)).donnee).mutex));
  746:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  747:                         element_courant)).donnee).mutex));
  748:                 liberation(s_etat_processus, (*((struct_liste_chainee *)
  749:                         element_courant)).donnee);
  750:                 free((struct_liste_chainee *) element_courant);
  751: 
  752:                 element_courant = element_suivant;
  753:             }
  754: 
  755:             element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
  756:             while(element_courant != NULL)
  757:             {
  758:                 element_suivant = (*((struct_liste_chainee *)
  759:                         element_courant)).suivant;
  760: 
  761:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  762:                         element_courant)).donnee).mutex));
  763:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  764:                         element_courant)).donnee).mutex));
  765:                 liberation(s_etat_processus,
  766:                         (*((struct_liste_chainee *)
  767:                         element_courant)).donnee);
  768:                 free((struct_liste_chainee *) element_courant);
  769: 
  770:                 element_courant = element_suivant;
  771:             }
  772: 
  773:             for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
  774:                     i++)
  775:             {
  776:                 free((*s_etat_processus).s_instructions_externes[i].nom);
  777:                 free((*s_etat_processus).s_instructions_externes[i]
  778:                         .nom_bibliotheque);
  779:             }
  780: 
  781:             if ((*s_etat_processus).nombre_instructions_externes != 0)
  782:             {
  783:                 free((*s_etat_processus).s_instructions_externes);
  784:             }
  785: 
  786:             element_courant = (*s_etat_processus).s_bibliotheques;
  787:             while(element_courant != NULL)
  788:             {
  789:                 element_suivant = (*((struct_liste_chainee *)
  790:                         element_courant)).suivant;
  791: 
  792:                 element_candidat = (*candidat).s_bibliotheques;
  793:                 while(element_candidat != NULL)
  794:                 {
  795:                     if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
  796:                             element_courant)).donnee))
  797:                             .descripteur == (*((struct_bibliotheque *)
  798:                             (*((struct_liste_chainee *) element_candidat))
  799:                             .donnee)).descripteur) &&
  800:                             ((*((struct_bibliotheque *)
  801:                             (*((struct_liste_chainee *) element_courant))
  802:                             .donnee)).pid == (*((struct_bibliotheque *)
  803:                             (*((struct_liste_chainee *) element_candidat))
  804:                             .donnee)).pid) && (pthread_equal(
  805:                             (*((struct_bibliotheque *)
  806:                             (*((struct_liste_chainee *) element_courant))
  807:                             .donnee)).tid, (*((struct_bibliotheque *)
  808:                             (*((struct_liste_chainee *) element_candidat))
  809:                             .donnee)).tid) != 0))
  810:                     {
  811:                         break;
  812:                     }
  813: 
  814:                     element_candidat = (*((struct_liste_chainee *)
  815:                             element_candidat)).suivant;
  816:                 }
  817: 
  818:                 if (element_candidat == NULL)
  819:                 {
  820:                     dlclose((*((struct_bibliotheque *)
  821:                             (*((struct_liste_chainee *) element_courant))
  822:                             .donnee)).descripteur);
  823:                 }
  824: 
  825:                 free((*((struct_bibliotheque *)
  826:                         (*((struct_liste_chainee *)
  827:                         element_courant)).donnee)).nom);
  828:                 free((*((struct_liste_chainee *) element_courant)).donnee);
  829:                 free(element_courant);
  830: 
  831:                 element_courant = element_suivant;
  832:             }
  833: 
  834:             element_courant = (*s_etat_processus).l_base_pile_last;
  835:             while(element_courant != NULL)
  836:             {
  837:                 element_suivant = (*((struct_liste_chainee *)
  838:                         element_courant)).suivant;
  839: 
  840:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  841:                         element_courant)).donnee).mutex));
  842:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  843:                         element_courant)).donnee).mutex));
  844:                 liberation(s_etat_processus,
  845:                         (*((struct_liste_chainee *) element_courant)).donnee);
  846:                 free(element_courant);
  847: 
  848:                 element_courant = element_suivant;
  849:             }
  850: 
  851:             element_courant = (*s_etat_processus).l_base_pile_systeme;
  852:             while(element_courant != NULL)
  853:             {
  854:                 element_suivant = (*((struct_liste_pile_systeme *)
  855:                         element_courant)).suivant;
  856: 
  857:                 if ((*((struct_liste_pile_systeme *)
  858:                         element_courant)).indice_boucle != NULL)
  859:                 {
  860:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
  861:                             element_courant)).indice_boucle).mutex));
  862:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
  863:                             element_courant)).indice_boucle).mutex));
  864:                 }
  865: 
  866:                 liberation(s_etat_processus,
  867:                         (*((struct_liste_pile_systeme *)
  868:                         element_courant)).indice_boucle);
  869: 
  870:                 if ((*((struct_liste_pile_systeme *)
  871:                         element_courant)).limite_indice_boucle != NULL)
  872:                 {
  873:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
  874:                             element_courant)).limite_indice_boucle).mutex));
  875:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
  876:                             element_courant)).limite_indice_boucle).mutex));
  877:                 }
  878: 
  879:                 liberation(s_etat_processus,
  880:                         (*((struct_liste_pile_systeme *)
  881:                         element_courant)).limite_indice_boucle);
  882: 
  883:                 if ((*((struct_liste_pile_systeme *)
  884:                         element_courant)).objet_de_test != NULL)
  885:                 {
  886:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
  887:                             element_courant)).objet_de_test).mutex));
  888:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
  889:                             element_courant)).objet_de_test).mutex));
  890:                 }
  891: 
  892:                 liberation(s_etat_processus,
  893:                         (*((struct_liste_pile_systeme *)
  894:                         element_courant)).objet_de_test);
  895: 
  896:                 if ((*((struct_liste_pile_systeme *)
  897:                         element_courant)).nom_variable != NULL)
  898:                 {
  899:                     free((*((struct_liste_pile_systeme *)
  900:                             element_courant)).nom_variable);
  901:                 }
  902: 
  903:                 free(element_courant);
  904: 
  905:                 element_courant = element_suivant;
  906:             }
  907: 
  908:             element_courant = (*s_etat_processus).s_fichiers;
  909:             while(element_courant != NULL)
  910:             {
  911:                 element_suivant = (*((struct_liste_chainee *)
  912:                         element_courant)).suivant;
  913: 
  914:                 element_candidat = (*candidat).s_fichiers;
  915:                 while(element_candidat != NULL)
  916:                 {
  917:                     if (((*((struct_descripteur_fichier *)
  918:                             (*((struct_liste_chainee *) element_courant))
  919:                             .donnee)).descripteur ==
  920:                             (*((struct_descripteur_fichier *)
  921:                             (*((struct_liste_chainee *) element_candidat))
  922:                             .donnee)).descripteur) &&
  923:                             ((*((struct_descripteur_fichier *)
  924:                             (*((struct_liste_chainee *) element_courant))
  925:                             .donnee)).pid ==
  926:                             (*((struct_descripteur_fichier *)
  927:                             (*((struct_liste_chainee *) element_candidat))
  928:                             .donnee)).pid) && (pthread_equal(
  929:                             (*((struct_descripteur_fichier *)
  930:                             (*((struct_liste_chainee *) element_courant))
  931:                             .donnee)).tid, (*((struct_descripteur_fichier *)
  932:                             (*((struct_liste_chainee *) element_candidat))
  933:                             .donnee)).tid) != 0))
  934:                     {
  935:                         break;
  936:                     }
  937: 
  938:                     element_candidat = (*((struct_liste_chainee *)
  939:                             element_candidat)).suivant;
  940:                 }
  941: 
  942:                 if (element_candidat == NULL)
  943:                 {
  944:                     fclose((*((struct_descripteur_fichier *)
  945:                             (*((struct_liste_chainee *) element_courant))
  946:                             .donnee)).descripteur);
  947:                 }
  948: 
  949:                 free((*((struct_descripteur_fichier *)
  950:                         (*((struct_liste_chainee *)
  951:                         element_courant)).donnee)).nom);
  952:                 free((struct_descripteur_fichier *)
  953:                         (*((struct_liste_chainee *)
  954:                         element_courant)).donnee);
  955:                 free(element_courant);
  956: 
  957:                 element_courant = element_suivant;
  958:             }
  959: 
  960:             element_courant = (*s_etat_processus).s_sockets;
  961:             while(element_courant != NULL)
  962:             {
  963:                 element_suivant = (*((struct_liste_chainee *)
  964:                         element_courant)).suivant;
  965: 
  966:                 element_candidat = (*candidat).s_sockets;
  967:                 while(element_candidat != NULL)
  968:                 {
  969:                     if (((*((struct_socket *)
  970:                             (*((struct_liste_chainee *) element_courant))
  971:                             .donnee)).socket == (*((struct_socket *)
  972:                             (*((struct_liste_chainee *) element_candidat))
  973:                             .donnee)).socket) &&
  974:                             ((*((struct_socket *)
  975:                             (*((struct_liste_chainee *) element_courant))
  976:                             .donnee)).pid == (*((struct_socket *)
  977:                             (*((struct_liste_chainee *) element_candidat))
  978:                             .donnee)).pid) && (pthread_equal(
  979:                             (*((struct_socket *)
  980:                             (*((struct_liste_chainee *) element_courant))
  981:                             .donnee)).tid, (*((struct_socket *)
  982:                             (*((struct_liste_chainee *) element_candidat))
  983:                             .donnee)).tid) != 0))
  984:                     {
  985:                         break;
  986:                     }
  987: 
  988:                     element_candidat = (*((struct_liste_chainee *)
  989:                             element_candidat)).suivant;
  990:                 }
  991: 
  992:                 if (element_candidat == NULL)
  993:                 {
  994:                     if ((*((struct_socket *) (*((struct_liste_chainee *)
  995:                             element_courant)).donnee)).socket_connectee
  996:                             == d_vrai)
  997:                     {
  998:                         shutdown((*((struct_socket *)
  999:                                 (*((struct_liste_chainee *) element_courant))
 1000:                                 .donnee)).socket, SHUT_RDWR);
 1001:                     }
 1002: 
 1003:                     close((*((struct_socket *)
 1004:                             (*((struct_liste_chainee *) element_courant))
 1005:                             .donnee)).socket);
 1006:                 }
 1007: 
 1008:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
 1009:                         element_courant)).donnee).mutex));
 1010:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
 1011:                         element_courant)).donnee).mutex));
 1012: 
 1013:                 liberation(s_etat_processus,
 1014:                         (*((struct_liste_chainee *)
 1015:                         element_courant)).donnee);
 1016:                 free(element_courant);
 1017: 
 1018:                 element_courant = element_suivant;
 1019:             }
 1020: 
 1021:             element_courant = (*s_etat_processus).s_connecteurs_sql;
 1022:             while(element_courant != NULL)
 1023:             {
 1024:                 element_suivant = (*((struct_liste_chainee *)
 1025:                         element_courant)).suivant;
 1026: 
 1027:                 element_candidat = (*candidat).s_connecteurs_sql;
 1028:                 while(element_candidat != NULL)
 1029:                 {
 1030:                     if (((
 1031: #ifdef MYSQL_SUPPORT
 1032:                             ((*((struct_connecteur_sql *)
 1033:                             (*((struct_liste_chainee *) element_courant))
 1034:                             .donnee)).descripteur.mysql ==
 1035:                             (*((struct_connecteur_sql *)
 1036:                             (*((struct_liste_chainee *) element_candidat))
 1037:                             .donnee)).descripteur.mysql)
 1038:                             &&
 1039:                             (strcmp((*((struct_connecteur_sql *)
 1040:                             (*((struct_liste_chainee *) element_courant))
 1041:                             .donnee)).type, "MYSQL") == 0)
 1042:                             &&
 1043:                             (strcmp((*((struct_connecteur_sql *)
 1044:                             (*((struct_liste_chainee *) element_candidat))
 1045:                             .donnee)).type, "MYSQL") == 0)
 1046: #else
 1047:                             0
 1048: #endif
 1049:                             ) || (
 1050: #ifdef POSTGRESQL_SUPPORT
 1051:                             ((*((struct_connecteur_sql *)
 1052:                             (*((struct_liste_chainee *) element_courant))
 1053:                             .donnee)).descripteur.postgresql ==
 1054:                             (*((struct_connecteur_sql *)
 1055:                             (*((struct_liste_chainee *) element_candidat))
 1056:                             .donnee)).descripteur.postgresql)
 1057:                             &&
 1058:                             (strcmp((*((struct_connecteur_sql *)
 1059:                             (*((struct_liste_chainee *) element_courant))
 1060:                             .donnee)).type, "POSTGRESQL") == 0)
 1061:                             &&
 1062:                             (strcmp((*((struct_connecteur_sql *)
 1063:                             (*((struct_liste_chainee *) element_candidat))
 1064:                             .donnee)).type, "POSTGRESQL") == 0)
 1065: #else
 1066:                             0
 1067: #endif
 1068:                             )) &&
 1069:                             ((*((struct_connecteur_sql *)
 1070:                             (*((struct_liste_chainee *) element_courant))
 1071:                             .donnee)).pid == (*((struct_connecteur_sql *)
 1072:                             (*((struct_liste_chainee *) element_candidat))
 1073:                             .donnee)).pid) && (pthread_equal(
 1074:                             (*((struct_connecteur_sql *)
 1075:                             (*((struct_liste_chainee *) element_courant))
 1076:                             .donnee)).tid, (*((struct_connecteur_sql *)
 1077:                             (*((struct_liste_chainee *) element_candidat))
 1078:                             .donnee)).tid) != 0))
 1079:                     {
 1080:                         break;
 1081:                     }
 1082: 
 1083:                     element_candidat = (*((struct_liste_chainee *)
 1084:                             element_candidat)).suivant;
 1085:                 }
 1086: 
 1087:                 if (element_candidat == NULL)
 1088:                 {
 1089:                     sqlclose((*((struct_liste_chainee *) element_courant))
 1090:                             .donnee);
 1091:                 }
 1092: 
 1093:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
 1094:                         element_courant)).donnee).mutex));
 1095:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
 1096:                         element_courant)).donnee).mutex));
 1097: 
 1098:                 liberation(s_etat_processus, (*((struct_liste_chainee *)
 1099:                         element_courant)).donnee);
 1100:                 free(element_courant);
 1101: 
 1102:                 element_courant = element_suivant;
 1103:             }
 1104: 
 1105:             element_courant = (*s_etat_processus).s_marques;
 1106:             while(element_courant != NULL)
 1107:             {
 1108:                 free((*((struct_marque *) element_courant)).label);
 1109:                 free((*((struct_marque *) element_courant)).position);
 1110:                 element_suivant = (*((struct_marque *) element_courant))
 1111:                         .suivant;
 1112:                 free(element_courant);
 1113:                 element_courant = element_suivant;
 1114:             }
 1115: 
 1116:             liberation_allocateur(s_etat_processus);
 1117: 
 1118:             sem_post(&((*s_etat_processus).semaphore_fork));
 1119:             sem_destroy(&((*s_etat_processus).semaphore_fork));
 1120: 
 1121:             free(s_etat_processus);
 1122: 
 1123:             s_etat_processus = candidat;
 1124:         }
 1125: 
 1126:         l_element_suivant = (*l_element_courant).suivant;
 1127: 
 1128:         free((struct_thread *) (*l_element_courant).donnee);
 1129:         free((struct_liste_chainee *) l_element_courant);
 1130: 
 1131:         l_element_courant = l_element_suivant;
 1132:     }
 1133: 
 1134:     liste_threads = NULL;
 1135: 
 1136:     l_element_courant = liste_threads_surveillance;
 1137: 
 1138:     while(l_element_courant != NULL)
 1139:     {
 1140:         s_argument_thread = (struct_descripteur_thread *)
 1141:                 (*l_element_courant).donnee;
 1142: 
 1143:         close((*s_argument_thread).pipe_objets[0]);
 1144:         close((*s_argument_thread).pipe_acquittement[1]);
 1145:         close((*s_argument_thread).pipe_injections[1]);
 1146:         close((*s_argument_thread).pipe_nombre_injections[1]);
 1147:         close((*s_argument_thread).pipe_nombre_objets_attente[0]);
 1148:         close((*s_argument_thread).pipe_interruptions[0]);
 1149:         close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
 1150: 
 1151:         if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
 1152:         {
 1153:             (*s_etat_processus).erreur_systeme = d_es_processus;
 1154:             return;
 1155:         }
 1156: 
 1157:         (*s_argument_thread).nombre_references--;
 1158: 
 1159:         BUG((*s_argument_thread).nombre_references < 0,
 1160:                 printf("(*s_argument_thread).nombre_references = %d\n",
 1161:                 (int) (*s_argument_thread).nombre_references));
 1162: 
 1163:         if ((*s_argument_thread).nombre_references == 0)
 1164:         {
 1165:             if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
 1166:             {
 1167:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 1168:                 return;
 1169:             }
 1170: 
 1171:             pthread_mutex_destroy(&((*s_argument_thread).mutex));
 1172:             free(s_argument_thread);
 1173:         }
 1174:         else
 1175:         {
 1176:             if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
 1177:             {
 1178:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 1179:                 return;
 1180:             }
 1181:         }
 1182: 
 1183:         l_element_suivant = (*l_element_courant).suivant;
 1184:         free((struct_liste_chainee *) l_element_courant);
 1185:         l_element_courant = l_element_suivant;
 1186:     }
 1187: 
 1188:     liste_threads_surveillance = NULL;
 1189: 
 1190:     if (sem_post(&semaphore_liste_threads) != 0)
 1191:     {
 1192:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1193:         (*s_etat_processus).erreur_systeme = d_es_processus;
 1194:         return;
 1195:     }
 1196: 
 1197:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1198:     sigpending(&set);
 1199:     return;
 1200: }
 1201: 
 1202: static struct_processus *
 1203: recherche_thread(pid_t pid, pthread_t tid)
 1204: {
 1205:     volatile struct_liste_chainee_volatile      *l_element_courant;
 1206: 
 1207:     struct_processus                            *s_etat_processus;
 1208: 
 1209:     l_element_courant = liste_threads;
 1210: 
 1211:     while(l_element_courant != NULL)
 1212:     {
 1213:         if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
 1214:                 .tid, tid) != 0) && ((*((struct_thread *)
 1215:                 (*l_element_courant).donnee)).pid == pid))
 1216:         {
 1217:             break;
 1218:         }
 1219: 
 1220:         l_element_courant = (*l_element_courant).suivant;
 1221:     }
 1222: 
 1223:     if (l_element_courant == NULL)
 1224:     {
 1225:         /*
 1226:          * Le processus n'existe plus. On ne distribue aucun signal.
 1227:          */
 1228: 
 1229:         return(NULL);
 1230:     }
 1231: 
 1232:     s_etat_processus = (*((struct_thread *)
 1233:             (*l_element_courant).donnee)).s_etat_processus;
 1234: 
 1235:     return(s_etat_processus);
 1236: }
 1237: 
 1238: static logical1
 1239: recherche_thread_principal(pid_t pid, pthread_t *thread)
 1240: {
 1241:     volatile struct_liste_chainee_volatile      *l_element_courant;
 1242: 
 1243:     l_element_courant = liste_threads;
 1244: 
 1245:     while(l_element_courant != NULL)
 1246:     {
 1247:         if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
 1248:                 == d_vrai) && ((*((struct_thread *)
 1249:                 (*l_element_courant).donnee)).pid == pid))
 1250:         {
 1251:             break;
 1252:         }
 1253: 
 1254:         l_element_courant = (*l_element_courant).suivant;
 1255:     }
 1256: 
 1257:     if (l_element_courant == NULL)
 1258:     {
 1259:         /*
 1260:          * Le processus n'existe plus. On ne distribue aucun signal.
 1261:          */
 1262: 
 1263:         return(d_faux);
 1264:     }
 1265: 
 1266:     (*thread) = (*((struct_thread *) (*l_element_courant).donnee)).tid;
 1267: 
 1268:     return(d_vrai);
 1269: }
 1270: 
 1271: 
 1272: /*
 1273: ================================================================================
 1274:   Procédures de gestion des signaux d'interruption
 1275: ================================================================================
 1276:   Entrée : variable globale
 1277: --------------------------------------------------------------------------------
 1278:   Sortie : variable globale modifiée
 1279: --------------------------------------------------------------------------------
 1280:   Effets de bord : néant
 1281: ================================================================================
 1282: */
 1283: 
 1284: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
 1285: // des signaux asynchrones. Elles de doivent pas bloquer dans le cas où
 1286: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
 1287: 
 1288: static inline void
 1289: verrouillage_gestionnaire_signaux()
 1290: {
 1291:     int         semaphore;
 1292: 
 1293:     sigset_t    oldset;
 1294:     sigset_t    set;
 1295: 
 1296:     sem_t       *sem;
 1297: 
 1298:     if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
 1299:             != NULL)
 1300:     {
 1301:         if (sem_post(sem) != 0)
 1302:         {
 1303:             BUG(1, uprintf("Lock error !\n"));
 1304:             return;
 1305:         }
 1306:     }
 1307: 
 1308:     // Il faut respecteur l'atomicité des deux opérations suivantes !
 1309: 
 1310:     sigfillset(&set);
 1311:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
 1312: 
 1313:     while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
 1314:     {
 1315:         if (errno != EINTR)
 1316:         {
 1317:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1318:             BUG(1, uprintf("Unlock error !\n"));
 1319:             return;
 1320:         }
 1321:     }
 1322: 
 1323:     if (sem_post(&semaphore_gestionnaires_signaux) == -1)
 1324:     {
 1325:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1326:         BUG(1, uprintf("Lock error !\n"));
 1327:         return;
 1328:     }
 1329: 
 1330:     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
 1331:     {
 1332:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1333:         BUG(1, uprintf("Lock error !\n"));
 1334:         return;
 1335:     }
 1336: 
 1337:     if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
 1338:     {
 1339:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1340:         BUG(1, uprintf("Unlock error !\n"));
 1341:         return;
 1342:     }
 1343: 
 1344:     if (semaphore == 1)
 1345:     {
 1346:         // Le semaphore ne peut être pris par le thread qui a appelé
 1347:         // le gestionnaire de signal car le signal est bloqué par ce thread
 1348:         // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
 1349:         // par un thread concurrent. On essaye donc de le bloquer jusqu'à
 1350:         // ce que ce soit possible.
 1351: 
 1352:         while(sem_trywait(&semaphore_liste_threads) == -1)
 1353:         {
 1354:             if ((errno != EINTR) && (errno != EAGAIN))
 1355:             {
 1356:                 pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1357: 
 1358:                 while(sem_wait(sem) == -1)
 1359:                 {
 1360:                     if (errno != EINTR)
 1361:                     {
 1362:                         BUG(1, uprintf("Lock error !\n"));
 1363:                         return;
 1364:                     }
 1365:                 }
 1366: 
 1367:                 BUG(1, uprintf("Lock error !\n"));
 1368:                 return;
 1369:             }
 1370: 
 1371:             sched_yield();
 1372:         }
 1373:     }
 1374: 
 1375:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1376:     sigpending(&set);
 1377: 
 1378:     return;
 1379: }
 1380: 
 1381: static inline void
 1382: deverrouillage_gestionnaire_signaux()
 1383: {
 1384:     int         semaphore;
 1385: 
 1386:     sem_t       *sem;
 1387: 
 1388:     sigset_t    oldset;
 1389:     sigset_t    set;
 1390: 
 1391:     // Il faut respecteur l'atomicité des deux opérations suivantes !
 1392: 
 1393:     sigfillset(&set);
 1394:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
 1395: 
 1396:     while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
 1397:     {
 1398:         if (errno != EINTR)
 1399:         {
 1400:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1401:             BUG(1, uprintf("Unlock error !\n"));
 1402:             return;
 1403:         }
 1404:     }
 1405: 
 1406:     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
 1407:     {
 1408:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1409:         BUG(1, uprintf("Unlock error !\n"));
 1410:         return;
 1411:     }
 1412: 
 1413:     while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
 1414:     {
 1415:         if (errno != EINTR)
 1416:         {
 1417:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1418:             BUG(1, uprintf("Unlock error !\n"));
 1419:             return;
 1420:         }
 1421:     }
 1422: 
 1423:     if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
 1424:     {
 1425:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1426:         BUG(1, uprintf("Unlock error !\n"));
 1427:         return;
 1428:     }
 1429: 
 1430:     if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
 1431:             != NULL)
 1432:     {
 1433:         while(sem_wait(sem) == -1)
 1434:         {
 1435:             if (errno != EINTR)
 1436:             {
 1437:                 pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1438:                 BUG(1, uprintf("Unlock error !\n"));
 1439:                 return;
 1440:             }
 1441:         }
 1442:     }
 1443: 
 1444:     if (semaphore == 1)
 1445:     {
 1446:         if (sem_post(&semaphore_liste_threads) != 0)
 1447:         {
 1448:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1449: 
 1450:             BUG(1, uprintf("Unlock error !\n"));
 1451:             return;
 1452:         }
 1453:     }
 1454: 
 1455:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1456:     sigpending(&set);
 1457: 
 1458:     return;
 1459: }
 1460: 
 1461: void
 1462: interruption1(int signal, siginfo_t *siginfo, void *context)
 1463: {
 1464:     pthread_t               thread;
 1465: 
 1466:     struct_processus        *s_etat_processus;
 1467: 
 1468:     volatile sig_atomic_t   exclusion = 0;
 1469: 
 1470:     verrouillage_gestionnaire_signaux();
 1471: 
 1472:     switch(signal)
 1473:     {
 1474:         case SIGALRM :
 1475:         {
 1476:             if ((*siginfo).si_pid == getpid())
 1477:             {
 1478:                 if ((s_etat_processus = recherche_thread(getpid(),
 1479:                         pthread_self())) == NULL)
 1480:                 {
 1481:                     deverrouillage_gestionnaire_signaux();
 1482:                     return;
 1483:                 }
 1484: 
 1485:                 if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1486:                 {
 1487:                     printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
 1488:                             (unsigned long long) pthread_self());
 1489:                     fflush(stdout);
 1490:                 }
 1491: 
 1492:                 if ((*s_etat_processus).pid_processus_pere != getpid())
 1493:                 {
 1494:                     kill((*s_etat_processus).pid_processus_pere, signal);
 1495:                 }
 1496:                 else
 1497:                 {
 1498:                     (*s_etat_processus).var_volatile_alarme = -1;
 1499:                     (*s_etat_processus).var_volatile_requete_arret = -1;
 1500:                 }
 1501:             }
 1502:             else
 1503:             {
 1504:                 if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1505:                 {
 1506:                     pthread_kill(thread, signal);
 1507:                 }
 1508:             }
 1509: 
 1510:             break;
 1511:         }
 1512: 
 1513:         case SIGINT :
 1514:         {
 1515:             /*
 1516:              * Une vieille spécification POSIX permet au pointeur siginfo
 1517:              * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
 1518:              * Solaris suit en particulier cette spécification.
 1519:              */
 1520: 
 1521:             if (siginfo == NULL)
 1522:             {
 1523:                 kill(getpid(), signal);
 1524:             }
 1525:             else if ((*siginfo).si_pid == getpid())
 1526:             {
 1527:                 if ((s_etat_processus = recherche_thread(getpid(),
 1528:                         pthread_self())) == NULL)
 1529:                 {
 1530:                     deverrouillage_gestionnaire_signaux();
 1531:                     return;
 1532:                 }
 1533: 
 1534:                 if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1535:                 {
 1536:                     printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
 1537:                             (unsigned long long) pthread_self());
 1538:                     fflush(stdout);
 1539:                 }
 1540: 
 1541:                 if ((*s_etat_processus).pid_processus_pere != getpid())
 1542:                 {
 1543:                     kill((*s_etat_processus).pid_processus_pere, signal);
 1544:                 }
 1545:                 else
 1546:                 {
 1547:                     (*s_etat_processus).var_volatile_traitement_sigint = -1;
 1548: 
 1549:                     while(exclusion == 1);
 1550:                     exclusion = 1;
 1551: 
 1552:                     if ((*s_etat_processus).var_volatile_requete_arret == -1)
 1553:                     {
 1554:                         deverrouillage_gestionnaire_signaux();
 1555:                         exclusion = 0;
 1556:                         return;
 1557:                     }
 1558: 
 1559:                     if (strncmp(getenv("LANG"), "fr", 2) == 0)
 1560:                     {
 1561:                         printf("+++Interruption\n");
 1562:                     }
 1563:                     else
 1564:                     {
 1565:                         printf("+++Interrupt\n");
 1566:                     }
 1567: 
 1568:                     fflush(stdout);
 1569: 
 1570:                     (*s_etat_processus).var_volatile_requete_arret = -1;
 1571:                     (*s_etat_processus).var_volatile_alarme = -1;
 1572: 
 1573:                     exclusion = 0;
 1574:                 }
 1575:             }
 1576:             else
 1577:             {
 1578:                 if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1579:                 {
 1580:                     pthread_kill(thread, signal);
 1581:                 }
 1582:             }
 1583: 
 1584:             break;
 1585:         }
 1586: 
 1587:         default :
 1588:         {
 1589:             BUG(1, uprintf("[%d] Unknown signal %d in this context\n",
 1590:                     (int) getpid(), signal));
 1591:             break;
 1592:         }
 1593:     }
 1594: 
 1595:     deverrouillage_gestionnaire_signaux();
 1596:     return;
 1597: }
 1598: 
 1599: void
 1600: interruption2(int signal, siginfo_t *siginfo, void *context)
 1601: {
 1602:     pthread_t               thread;
 1603:     struct_processus        *s_etat_processus;
 1604: 
 1605:     verrouillage_gestionnaire_signaux();
 1606: 
 1607:     if (siginfo == NULL)
 1608:     {
 1609:         /*
 1610:          * Le signal SIGFSTP provient de la mort du processus de contrôle.
 1611:          * Sous certains systèmes (Linux...), la mort du terminal de contrôle
 1612:          * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
 1613:          * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
 1614:          * non initialisée (pointeur NULL) issue de TERMIO.
 1615:          */
 1616: 
 1617:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1618:         {
 1619:             pthread_kill(thread, SIGHUP);
 1620:             deverrouillage_gestionnaire_signaux();
 1621:             return;
 1622:         }
 1623:     }
 1624:     else if ((*siginfo).si_pid == getpid())
 1625:     {
 1626:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 1627:                 == NULL)
 1628:         {
 1629:             deverrouillage_gestionnaire_signaux();
 1630:             return;
 1631:         }
 1632: 
 1633:         /*
 1634:          *  0 => fonctionnement normal
 1635:          * -1 => requête
 1636:          *  1 => requête acceptée en attente de traitement
 1637:          */
 1638: 
 1639:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1640:         {
 1641:             printf("[%d] SIGTSTP (thread %llu)\n", (int) getpid(),
 1642:                     (unsigned long long) pthread_self());
 1643:             fflush(stdout);
 1644:         }
 1645: 
 1646:         if ((*s_etat_processus).var_volatile_processus_pere == 0)
 1647:         {
 1648:             kill((*s_etat_processus).pid_processus_pere, signal);
 1649:         }
 1650:         else
 1651:         {
 1652:             (*s_etat_processus).var_volatile_requete_arret2 = -1;
 1653:         }
 1654:     }
 1655:     else
 1656:     {
 1657:         // Envoi d'un signal au thread maître du groupe.
 1658: 
 1659:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1660:         {
 1661:             pthread_kill(thread, SIGTSTP);
 1662:             deverrouillage_gestionnaire_signaux();
 1663:             return;
 1664:         }
 1665:     }
 1666: 
 1667:     deverrouillage_gestionnaire_signaux();
 1668:     return;
 1669: }
 1670: 
 1671: void
 1672: interruption3(int signal, siginfo_t *siginfo, void *context)
 1673: {
 1674:     struct_processus        *s_etat_processus;
 1675: 
 1676:     static int              compteur = 0;
 1677: 
 1678:     verrouillage_gestionnaire_signaux();
 1679: 
 1680:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1681:     {
 1682:         deverrouillage_gestionnaire_signaux();
 1683:         return;
 1684:     }
 1685: 
 1686:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1687:     {
 1688:         printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
 1689:                 (unsigned long long) pthread_self());
 1690:         fflush(stdout);
 1691:     }
 1692: 
 1693:     if ((*s_etat_processus).var_volatile_recursivite == -1)
 1694:     {
 1695:         // Segfault dans un appel de fonction récursive
 1696:         deverrouillage_gestionnaire_signaux();
 1697:         longjmp(contexte, -1);
 1698:     }
 1699:     else
 1700:     {
 1701:         // Segfault dans une routine interne
 1702:         if (strncmp(getenv("LANG"), "fr", 2) == 0)
 1703:         {
 1704:             printf("+++Système : Violation d'accès (dépassement de pile)\n");
 1705:         }
 1706:         else
 1707:         {
 1708:             printf("+++System : Access violation (stack overflow)\n");
 1709:         }
 1710: 
 1711:         fflush(stdout);
 1712: 
 1713:         compteur++;
 1714: 
 1715:         if (compteur > 1)
 1716:         {
 1717:             deverrouillage_gestionnaire_signaux();
 1718:             exit(EXIT_FAILURE);
 1719:         }
 1720:         else
 1721:         {
 1722:             deverrouillage_gestionnaire_signaux();
 1723:             longjmp(contexte_initial, -1);
 1724:         }
 1725:     }
 1726: 
 1727:     deverrouillage_gestionnaire_signaux();
 1728:     return;
 1729: }
 1730: 
 1731: void
 1732: interruption4(int signal, siginfo_t *siginfo, void *context)
 1733: {
 1734:     struct_processus        *s_etat_processus;
 1735: 
 1736:     verrouillage_gestionnaire_signaux();
 1737: 
 1738:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1739:     {
 1740:         deverrouillage_gestionnaire_signaux();
 1741:         return;
 1742:     }
 1743: 
 1744:     /*
 1745:      * Démarrage d'un processus fils ou gestion de SIGCONT (SUSPEND)
 1746:      */
 1747: 
 1748:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1749:     {
 1750:         printf("[%d] SIGSTART/SIGCONT (thread %llu)\n", (int) getpid(),
 1751:                 (unsigned long long) pthread_self());
 1752:         fflush(stdout);
 1753:     }
 1754: 
 1755:     deverrouillage_gestionnaire_signaux();
 1756:     return;
 1757: }
 1758: 
 1759: void
 1760: interruption5(int signal, siginfo_t *siginfo, void *context)
 1761: {
 1762:     pthread_t               thread;
 1763:     struct_processus        *s_etat_processus;
 1764: 
 1765:     verrouillage_gestionnaire_signaux();
 1766: 
 1767:     if ((*siginfo).si_pid == getpid())
 1768:     {
 1769:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 1770:                 == NULL)
 1771:         {
 1772:             deverrouillage_gestionnaire_signaux();
 1773:             return;
 1774:         }
 1775: 
 1776:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1777:         {
 1778:             printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
 1779:                     (unsigned long long) pthread_self());
 1780:             fflush(stdout);
 1781:         }
 1782: 
 1783:         /*
 1784:          * var_globale_traitement_retarde_stop :
 1785:          *  0 -> traitement immédiat
 1786:          *  1 -> traitement retardé (aucun signal reçu)
 1787:          * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
 1788:          */
 1789: 
 1790:         if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
 1791:         {
 1792:             (*s_etat_processus).var_volatile_requete_arret = -1;
 1793:         }
 1794:         else
 1795:         {
 1796:             (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
 1797:         }
 1798:     }
 1799:     else
 1800:     {
 1801:         // Envoi d'un signal au thread maître du groupe.
 1802: 
 1803:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1804:         {
 1805:             pthread_kill(thread, SIGFSTOP);
 1806:             deverrouillage_gestionnaire_signaux();
 1807:             return;
 1808:         }
 1809:     }
 1810: 
 1811:     deverrouillage_gestionnaire_signaux();
 1812:     return;
 1813: }
 1814: 
 1815: void
 1816: interruption6(int signal, siginfo_t *siginfo, void *context)
 1817: {
 1818:     struct_processus        *s_etat_processus;
 1819: 
 1820:     verrouillage_gestionnaire_signaux();
 1821: 
 1822:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1823:     {
 1824:         deverrouillage_gestionnaire_signaux();
 1825:         return;
 1826:     }
 1827: 
 1828:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1829:     {
 1830:         printf("[%d] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
 1831:                 (unsigned long long) pthread_self());
 1832:         fflush(stdout);
 1833:     }
 1834: 
 1835:     deverrouillage_gestionnaire_signaux();
 1836:     return;
 1837: }
 1838: 
 1839: void
 1840: interruption7(int signal, siginfo_t *siginfo, void *context)
 1841: {
 1842:     struct_processus        *s_etat_processus;
 1843: 
 1844:     verrouillage_gestionnaire_signaux();
 1845: 
 1846:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1847:     {
 1848:         deverrouillage_gestionnaire_signaux();
 1849:         return;
 1850:     }
 1851: 
 1852:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1853:     {
 1854:         printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
 1855:                 (unsigned long long) pthread_self());
 1856:         fflush(stdout);
 1857:     }
 1858: 
 1859:     (*s_etat_processus).var_volatile_requete_arret = -1;
 1860:     deverrouillage_gestionnaire_signaux();
 1861: 
 1862:     BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
 1863:     return;
 1864: }
 1865: 
 1866: void
 1867: interruption8(int signal, siginfo_t *siginfo, void *context)
 1868: {
 1869:     pthread_t               thread;
 1870:     struct_processus        *s_etat_processus;
 1871: 
 1872:     verrouillage_gestionnaire_signaux();
 1873: 
 1874:     if ((*siginfo).si_pid == getpid())
 1875:     {
 1876:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 1877:                 == NULL)
 1878:         {
 1879:             deverrouillage_gestionnaire_signaux();
 1880:             return;
 1881:         }
 1882: 
 1883:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1884:         {
 1885:             printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
 1886:                     (unsigned long long) pthread_self());
 1887:             fflush(stdout);
 1888:         }
 1889: 
 1890:         (*s_etat_processus).var_volatile_alarme = -1;
 1891:         (*s_etat_processus).var_volatile_requete_arret = -1;
 1892:     }
 1893:     else
 1894:     {
 1895:         // Envoi d'un signal au thread maître du groupe.
 1896: 
 1897:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1898:         {
 1899:             pthread_kill(thread, SIGURG);
 1900:             deverrouillage_gestionnaire_signaux();
 1901:             return;
 1902:         }
 1903:     }
 1904: 
 1905:     deverrouillage_gestionnaire_signaux();
 1906:     return;
 1907: }
 1908: 
 1909: void
 1910: interruption9(int signal, siginfo_t *siginfo, void *context)
 1911: {
 1912:     struct_processus        *s_etat_processus;
 1913: 
 1914:     verrouillage_gestionnaire_signaux();
 1915: 
 1916:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1917:     {
 1918:         deverrouillage_gestionnaire_signaux();
 1919:         return;
 1920:     }
 1921: 
 1922:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1923:     {
 1924:         printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
 1925:                 (unsigned long long) pthread_self());
 1926:         fflush(stdout);
 1927:     }
 1928: 
 1929:     pthread_kill((*s_etat_processus).tid_processus_pere, SIGFSTOP);
 1930:     deverrouillage_gestionnaire_signaux();
 1931:     return;
 1932: }
 1933: 
 1934: void
 1935: interruption10(int signal, siginfo_t *siginfo, void *context)
 1936: {
 1937:     file                    *fichier;
 1938: 
 1939:     struct_processus        *s_etat_processus;
 1940: 
 1941:     unsigned char           nom[8 + 64 + 1];
 1942: 
 1943:     verrouillage_gestionnaire_signaux();
 1944: 
 1945:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1946:     {
 1947:         deverrouillage_gestionnaire_signaux();
 1948:         return;
 1949:     }
 1950: 
 1951:     snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
 1952:             (unsigned long) pthread_self());
 1953: 
 1954:     if ((fichier = fopen(nom, "w+")) != NULL)
 1955:     {
 1956:         fclose(fichier);
 1957: 
 1958:         freopen(nom, "w", stdout);
 1959:         freopen(nom, "w", stderr);
 1960:     }
 1961: 
 1962:     freopen("/dev/null", "r", stdin);
 1963: 
 1964:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1965:     {
 1966:         printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
 1967:                 (unsigned long long) pthread_self());
 1968:         fflush(stdout);
 1969:     }
 1970: 
 1971:     deverrouillage_gestionnaire_signaux();
 1972:     return;
 1973: }
 1974: 
 1975: void
 1976: traitement_exceptions_gsl(const char *reason, const char *file,
 1977:         int line, int gsl_errno)
 1978: {
 1979:     struct_processus        *s_etat_processus;
 1980: 
 1981:     verrouillage_gestionnaire_signaux();
 1982: 
 1983:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1984:     {
 1985:         deverrouillage_gestionnaire_signaux();
 1986:         return;
 1987:     }
 1988: 
 1989:     (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
 1990:     deverrouillage_gestionnaire_signaux();
 1991:     return;
 1992: }
 1993: 
 1994: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>