File:  [local] / rpl / src / interruptions.c
Revision 1.12: download - view: text, annotated - select for diffs - revision graph
Thu Apr 29 15:47:25 2010 UTC (14 years ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction de problèmes liées à des valeurs de sémaphores dans le cas
d'erreurs pour éviter les conditions bloquantes.

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

CVSweb interface <joel.bertrand@systella.fr>